【Java虚拟机】之五 语法糖的味道

简介

           语法糖,也称糖衣语法,是由英国计算机科学家彼得·约翰·兰达发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员开发使用。通常来说,使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。而 在Java中,常用的语法糖主要是泛型、变长参数、自动装箱/拆箱等


 泛型与类型擦除

           泛型是JDK 1.5 的一项新增特性,在此之前,Java只能通过 Object 是所有类型的父类和类型强制转换两个特点的配合来实现类型泛化。例如,在哈希表的存取中,JDK 1.5 之前使用 HashMap 的 get() 方法,返回值是一个Object对象,由于Java语言里面所有的类型都是继承于 java.lang.Object ,所以 Object 转型成任何对象都是有可能的。但也因为这样,就只有程序员和运行期的虚拟机才知道这个 Object 是个什么样的类型,而在编译期间编译器无法检查这个Object的转型是否成功,也就造成运行期很多 ClassCastException 的异常。

       类型擦除:

          Java语言中的泛型只存在于程序源码中,在编译后的字节码文件中,就已经替换为原来的原生类型,并且在相应的地方插入了强制类型转型代码,因此,对于运行期的Java语言来说,ArrayList<Integer> 与 ArrayList<String> 就是同一个类,所以泛型技术实际上是Java语言的一颗语法糖,Java 语言中的泛型实现方法称为类型擦除, 基于这种方法实现的泛型称为伪泛型。

下面是泛型擦除前和擦除后的例子:

	/**
	 * 泛型擦除前
	 */
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("haha", "哈哈");
		System.out.println(map.get("haha"));
	}

	/**
	 * 泛型擦除后
	 */
	public static void main(String[] args) {
		Map map = new HashMap();
		map.put("haha", "哈哈");
		System.out.println((String) map.get("haha"));
	}
如上代码,将第一段代码编译成Class文件后,在用字节码反编译工具进行反编译后,将会发现发型都不见了,程序又会变回了Java泛型出现前的写法,如第二段代码所示。

下面用代码来说明下类型擦除:
	public void method(List<String> list) {}
	public void method(List<Integer> list) {}
上面两个方法存在于同一类中编译时将会出现错误,因为类型擦除的原因,参数的泛型将会被擦除,变成了List,所以两个方法的方法名相同,参数相同,所以编译失败。


除了类型擦除之外,还有自动拆/装箱(这个主要方便基本数据类型和对应的包装类类型的转换),变长参数(在调用时变成数组类型的参数),高级 for 循环 (将代码还原成迭代器的实现)等这些,在这边就不详细介绍了。





猜你喜欢

转载自blog.csdn.net/qq_36712034/article/details/78154097