《深入理解java虛擬機》第十章 早期(編譯器)優化

java語法糖的味道

泛型與類型擦除

在java還沒有出現泛型之前,只能通過Object是所有類型的父類、類型強制轉換兩個特點的配合來實現類型泛化。

java中的泛型,只在程序源碼中存在,在編譯後的字節碼文件中,就已經替換爲原來的原生類型,並在相應地方插入了強制轉型代碼。List<String>和List<Integer>就是同一個類,泛型技術實際上是java語言的一顆語法糖。

java中的泛型實現方法稱爲類型擦除,基於這種方法實現的泛型稱爲僞泛型。

編譯前代碼

public static void main(String[] args) {
	Map<String, String> map = new HashMap<String, String>();
	map.put("hello", "你好");
	map.put("how are you?", "吃了沒?");
	System.out.println(map.get("hello"));
	System.out.println(map.get("how are you?"));
}

編譯後,反編譯後的代碼

public static void main(String[] args) {
	Map map = new HashMap();
	map.put("hello", "你好");
	map.put("how are you?", "吃了沒?");
	System.out.println((String) map.get("hello"));
	System.out.println((String) map.get("how are you?"));
}

自動裝箱、拆箱與遍歷循環(Foreach)

程序代碼

public static void main(String[] args) {
	List<Integer> list = Arrays.asList(1, 2, 3, 4);
	// 如果在JDK 1.7中,還有另外一顆語法糖 ,
	// 能讓上面這句代碼進一步簡寫成List<Integer> list = [1, 2, 3, 4];
	int sum = 0;
	for (int i : list) {
		sum += i;
	}
	System.out.println(sum);
}

編譯後,並反編譯的代碼

public static void main(String[] args) {
	List list = Arrays.asList( new Integer[] {
		 Integer.valueOf(1),
		 Integer.valueOf(2),
		 Integer.valueOf(3),
		 Integer.valueOf(4) });

	int sum = 0;
	for (Iterator localIterator = list.iterator(); localIterator.hasNext(); ) {
		int i = ((Integer)localIterator.next()).intValue();
		sum += i;
	}
	System.out.println(sum);
}


上述例子中,出現的語法糖:
    自動裝箱:Integer.valueOf()
    自動拆箱:  Integer.intValue()
    遍歷循環:還原爲迭代器
    不定參數:還原爲數組類型

條件編譯

許多語言支持條件編譯,如C、C++使用#ifdef來完成。
"java使用條件爲常量的if語句實現"。
如下,此代碼中的if語句不同於其他java代碼。它在編譯階段就會執行,生成的字節碼只包括System.out.println("block 1");
public static void main(String[] args) {
	if (true) {
		System.out.println("block 1");
	} else {
		System.out.println("block 2");
	}
}

編譯後,反編譯的代碼

public static void main(String[] args) {
	System.out.println("block 1");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章