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


