泛型是JDK1.5引入的概念,但泛型代码可以很好的和之前版本代码兼容。
原因:
因为泛型信息只存在于代码编译阶段,编译器编译完带有泛型的java程序后,生成的class文件中,已经将与泛型相关的信息擦除掉,以此使程序运行效率不受影响,这个过程叫做类型擦出,也即是说泛型类和普通类在java虚拟机是一样的。
泛型类List<String>和List<Integer>经过编译,被类型擦出后的类型均为java.util.ArrayList。
拓展:
由于编译生成的字节码会丢掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其他类型的数据(反射中的知识点);
jdk开发文档中Object类中有一个getClass()方法,返回Object的运行时类。
public class Test {
public static void main(String[] args) {
//SheepFold<Sheep> sheepFold = new SheepFold<Goat>(new Goat());
List<String> listStr = new ArrayList<>();
List<Integer> listInt = new ArrayList<>();
//getClass() 返回此Object的运行时类
System.out.println(listStr.getClass());
System.out.println(listInt .getClass());
System.out.println(listStr.getClass()==listInt .getClass());
}
}
运行结果如下:
"C:\Program Files\Java\jdk1.8.0_111\bin\java.exe" "-javaagent:C:\Program ……
parent\spring-aop\target\classes" com.learn.Test
class java.util.ArrayList
class java.util.ArrayList
true
通过上述事例,说明泛型概念只存在于编译阶段,运行时会进行擦出。一开始定义的,只能存储String、Integer的两个List擦除后都为ArrayList类型。