《深入理解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");
}

猜你喜欢

转载自blog.csdn.net/lik_lik/article/details/89339513