语法糖(Syntactic Sugar):也称糖衣语法,指在计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。通常来说,使用语法糖能够增加程序的可读性,减少程序代码出错的机会。
Java中的语法糖包括但不限于以下10颗:泛型与类型擦除、自动装箱和拆箱、遍历循环、变长参数、条件编译、内部类、枚举类、断言语句、对枚举和字符串的switch支持、在try语句中定义和关闭资源。
1.泛型与类型擦除
源代码:
- public static void main(String[] args){
- Map<String,Integer> map = new HashMap<String,Integer>();
- map.put("hello" , 1);
- map.put("world" , 2);
- System.out.println(map.get("hello"));
- System.out.println(map.get("world"));
- }
编译后的class文件:
- public static void main(String[] paramArrayOfString)
- {
- HashMap localHashMap = new HashMap();
- localHashMap.put("hello", Integer.valueOf(1));
- localHashMap.put("world", Integer.valueOf(2));
- System.out.println(localHashMap.get("hello"));
- System.out.println(localHashMap.get("world"));
- }
在编译后的字节码中,已经被替换为原来的原生类型了,所以有人说java的泛型是伪泛型
2.自动拆装箱
源代码:
- public static void main(String[] args) {
- Integer a = 1;
- Integer b = 2;
- Integer c = 3;
- Integer d = 3;
- Integer e = 321;
- Integer f = 321;
- Long g = 3L;
- System.out.println(c ==d ); //true
- System.out.println(e ==f ); //false
- System.out.println(c == (a+b)); //true
- System.out.println(c.equals(a+b)); //true
- System.out.println(g == (a+b)); //true
- System.out.println(g.equals(a + b)); //false
- }
编译后的class文件:
- public static void main(String[] args)
- {
- Integer a = Integer.valueOf(1);
- Integer b = Integer.valueOf(2);
- Integer c = Integer.valueOf(3);
- Integer d = Integer.valueOf(3);
- Integer e = Integer.valueOf(321);
- Integer f = Integer.valueOf(321);
- Long g = Long.valueOf(3L);
- System.out.println(c == d);
- System.out.println(e == f);
- System.out.println(c.intValue() == a.intValue() + b.intValue());
- System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue())));
- System.out.println(g.longValue() == a.intValue() + b.intValue());
- System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));
- }
包装类的"=="运算 在不遇到算数运算的情况下不会自动拆箱,equals也不会处理数据转型
3.条件编译
源代码:
- public static void main(String[] args){
- if(true){
- System.out.print("a");
- }else{
- System.out.print("b");
- }
- }
编译后的class文件:
- public static void main(String[] paramArrayOfString) {
- System.out.print("a");
- }
- }
条件编译可以帮助我们消除源代码中的一些死代码
4.变长参数
源代码:
- public static void main(String[] args) {
- Demo5.printParams(1, 2, 3, 4, 5);
- }
- public static void printParams(Integer... a) {
- Integer[] as = a;
- for(Integer i : as){
- System.out.println(i);
- }
- }
编译后的class文件:
- public static void main(String[] paramArrayOfString){
- printParams(new Integer[] { Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5) });
- }
- public static void printParams(Integer... paramVarArgs){
- Integer[] arrayOfInteger1 = paramVarArgs;
- for (Integer localInteger : arrayOfInteger1) {
- System.out.println(localInteger);
- }
- }
5.遍历与循环
源代码:
- public static void main(String[] args){
- List list1 = Arrays.asList(1,2,3,4,5);
- int sum = 0;
- for(int i : list1){
- sum += i;
- }
- System.out.println("sum is :"+sum);
- }
编译后的class文件:
- public static void main(String[] paramArrayOfString){
- List localList = Arrays.asList(new Integer[] { Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5) });
- int i = 0;
- for (Iterator localIterator = localList.iterator(); localIterator.hasNext();){
- int j = ((Integer)localIterator.next()).intValue();
- i += j;
- }
- System.out.println("sum is :" + i);
- }
从编译后的代码来看foreach在遍历时实际上还是调用了底层的迭代方法
6.内部类
源代码:
- public class Demo8 {
- class Demo8_1{
- private String name="";
- Demo8_1(String name){
- this.name = name;
- }
- }
- }
编译后的class文件:
- 有内部类会编译出多个class文件
- Demo8.class:
- public class Demo8{
- class Demo8_1{
- private String name = "";
- Demo8_1(String name){
- this.name = name;
- }
- }
- }
- Demo8$Demo8_1.class:
- class Demo8$Demo8_1{
- private String name = "";
- Demo8$Demo8_1(Demo8 paramDemo8, String name){
- this.name = name;
- }
- }
7.对字符串的switch支持(jdk1.7)
源代码:
- public static void stringSwitch() {
- String str = "a";
- switch (str) {
- case "a":
- System.out.println("a");
- break;
- case "b":
- System.out.println("b");
- break;
- default:
- System.out.println("default");
- break;
- }
- }
编译后的class文件:
- public static void stringSwitch() {
- String str = "a";
- String str1 = str;
- switch (str.hashCode()){
- case 97:
- if (str1.equals("a")) {
- break;
- }
- break;
- case 98:
- if (!str1.equals("b")){
- break label82;
- System.out.println("a");
- return;
- }else {
- System.out.println("b");
- }
- break;
- }
- label82:
- System.out.println("default");
- }
8.自动为try代码快中的资源进行关闭(jdk7中为大多数资源对象实现了AutoCloseable接口)
源代码:
- public static String readFirstLineFromFile(String path) throws IOException{
- try(BufferedReader br=new BufferedReader(new FileReader(path))){
- return br.readLine();
- }
- }
编译后的class文件:
- public static String readFirstLineFromFile(String path)
- throws IOException{
- Object localObject1 = null;Object localObject4 = null;
- Object localObject3;
- try{
- BufferedReader br = new BufferedReader(new FileReader(path));
- try {
- return br.readLine();
- }
- finally {
- if (br != null) {
- br.close();
- }
- }
- }
- finally {
- if (localObject2 == null) {
- localObject3 = localThrowable;
- } else if (localObject3 != localThrowable) {
- localObject3.addSuppressed(localThrowable);
- }
- }
- }
- 参考资料:《深入理解Java虚拟机》
- 反编译工具:JD-JUI
转载请注明:左手代码右手诗 » java语法糖的味道