语法糖(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语法糖的味道