泛型擦除指:在编译器存在泛型类型的代码进行编译生成字节码时,泛型类型T将不会存在于生成的字节码之中,所以同一个泛型在运行时期,不管他们泛型对应的实际类型是什么,他们的运行时class是相同的。
如:
List<String> l1 = newArrayList<String>();
List<Integer> l2 = newArrayList<Integer>();
System.out.println(l1.getClass() ==l2.getClass());//true
上面的两个list通过getClass获取的类信息是相同的,所以是true.
Java中的泛型被称之为伪泛型,因为编译形成字节码之后,泛型类型将不复存在,而代码中的泛型编译成字节码以后,在相应使用操作上对字节码的对泛型进行了强制类型转换,JDK5引入泛型以后编译字节码中新增了LocalVariableTypeTable(Signature)等属性来解决泛型参数识别问题(Java虚拟机2版),Signature作为字节码层面的特征签名,包含了参数化类型信息。
ClassA<T>是写的一个泛型类,可以看到字节码的localVariableTypeTable中存有实例ClassA的参数信息。
因为有了Signature属性,擦除操作仅是对字节码层面上的擦除,而元数据中还是有泛型类型信息的,所以通过反射手段可以获取到参数化类型。