泛型擦除
🐱🐉首先理解什么是类型擦除:Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。
🦄在编译代码阶段,ArrayList<H>
和ArrayList<D>
,编译器只认识ArrayList,而不认识后面的泛型信息。JVM看到的只是List,而由泛型附加的类型信息对JVM是看不到的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法在运行时刻出现的类型转换异常的情况,类型擦除也是Java的泛型与C++模板机制实现方式之间的重要区别。
考虑如下代码
ArrayList list=new ArrayList();
list.add("nishizhu");
t(list);
public static void t(ArrayList<Hero> s) {}
编译会通过,因为Hero被擦除了。
更如下代码,返回的是true;这就看出泛型信息被擦除了。
public class Test {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<String>();
list1.add("abc");
ArrayList<Integer> list2 = new ArrayList<Integer>();
list2.add(123);
System.out.println(list1.getClass() == list2.getClass());
}
}
原文写的更详细:泛型擦除和类型擦除带来的问题