不积跬步,无以至千里;不积小流,无以成江海。

java语法糖的味道

JAVA 康康 1239℃ 0评论

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

喜欢 (1)or分享 (0)
发表我的评论
取消评论

 

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址