1.泛型擦除
以ArrayList为例,ArrayList源码中具有泛型< E >,其中有这么一个方法
E elementData(int index) {
return (E) elementData[index];
}
可见elementData方法返回的是一个泛型对象E,
我们用代码看一下,如下:
public static void main(String[] args) throws Exception {
ArrayList<String> list = new ArrayList<>();
Method method = list.getClass().getDeclaredMethod("elementData", int.class);
System.out.println(method.getName() + " : " + method.getReturnType());
//结果是 :
//elementData : class java.lang.Object
}
可见泛型E已经被擦除为Object类型了,
那一定会擦除为Object类型吗?经验证,我们可以通过 (A是某个具体的类),即泛型类T其最大父类A,此时进行泛型擦除时会把T擦除为A,可把< T >视为 < T extend Object>。
2.泛型补偿
List<String> list = new ArrayList<>();
list.add("123");
String result = list.get(0);
System.out.println(result);
在ArrayList集合中,既然String类型在运行时期会被擦除为Object,那么整个List集合存储的也是Object,那通过list.get(0);获取到的为什么还是String类型的对象呢?不应该进行强制类型转换吗?
原理就是泛型的补偿机制,去除了强制类型转换的过程,可以直接获取编译器定义的对象类型。