Java(6-2)

来源:互联网 发布:frp需要域名吗 编辑:程序博客网 时间:2024/05/21 11:22

我们上回,对泛型类,方法,应用有了一个基本的认识,这回我们来说说泛型和虚拟机:

Part1:类型擦除
无论何时定义一个泛型类型,都自动提供了一个相应的原始类型。原始 类型的名字就是删去类型参数后的泛型类型名。擦除类型变量,并替换为限定类型(无限定的变量用Object)

当程序调用泛型方法时,如果擦除返回类型,编译器插入强制类型转换。例如下面的语句:

Pair<Employee> buddies = ...;Employee buddy = buddies.getFirst();

擦除getFirst的返回类型后将返回Object类型。编译器自动插入Employee的强制类型转换。也就是说,编译器把这个方法调用翻译为两条虚拟机指令:1.对原始方法Pair.getFirst的调用 2.将返回的Object类强制转换为Employee类型 。

同样的,在泛型方法中,也会存在类型擦除。方法:

public static <T extends Comparable> T min(T[] a)//这是没擦除的状态public static Comparable min(Comparable[] a)//这是擦除的状态

注意啊,类型参数T已经没了,而擦除类型之后,只剩下限定类型Comparable

总之,需要记住有关Java泛型转换的事实:
1.虚拟机中没有泛型,只有普通方法。
2.所有的类型参数都用它们的限定类型替换。
3.桥方法被合成来保持多态。
4.为保持类型安全性,必要时插入强制类型转换

Part3,Tip:
不能用基本类型实例化泛型的类型参数
不能用类型参数代替基本类型。因此,没有Pair,只有Pair。当然,其原因是类型擦除,Object中不能存储double值/

运行时类型查询只适用于原始类型
还是类型擦除,虚拟机只认识原始类型。

不能创建参数化类型的数组
还是类型擦除,你创建一个

public<String>[] table = new Pair<String>[10];//Error

在虚拟机眼中是这样:

Object[] objarry = table;

需要说明的是,不允许创建(new Pair[10])但是声明还是允许的(Pair[])

最后注意下通配符泛型:
泛型Pair类型,它的类型参数是Employee的子类,我们可以这样写:

Pair<?extends Employee>

同样的,如果他的类型参数是Manager的超类,可以这样:

Pair<?super Manager>
原创粉丝点击