Java中的泛型是伪泛型,在编译期间会将所有与泛型有关的信息去掉,替换为原始类型。把泛型类的字节码进行反编译就可以看到是没有的。
关于原始类型,如果使用了上界和下界通配符,那么原始类型就是上界和下界,如何没有就是默认的Object。
类型擦除所带来的问题
1、类型检查
泛型所提供的类型检查是在编译之前的。
那么,这个类型检查是针对谁的呢?我们先看看参数化类型和原始类型的兼容。
以 ArrayList举例子,在没有泛型之前的写法:
ArrayList list = new ArrayList();
有了泛型以后的写法:
ArrayList<String> list = new ArrayList<String>();
如果是与以前的代码兼容,有以下两种情况:
ArrayList<String> list1 = new ArrayList(); //第一种 情况
ArrayList list2 = new ArrayList<String>(); //第二种 情况
这样是没有错误的,不过会有个编译时警告:Raw use of parameterized class 'ArrayList'。
不过在第一种情况,可以实现与完全使用泛型参数一样的效果,第二种则没有效果。
因为类型检查就是针对引用的,谁是一个引用,用这个引用调用泛型方法,就会对这个引用调用的方法进行类型检测,而无关它真正引用的对象。
2、类型转换
既然编译之后的字节码文件中泛型被擦除了,那么是如何获取之前的与泛型有关的信息的呢?答案是获取时会进行类型转换。