Java的泛型是伪泛型,为什么这样说,因为Java的泛型仅在编译时起作用,在实际运行时会被替换为具体类型
且编译时只会对等号左边的对象起作用,等号右边的即使使用了泛型java编译时也不会检查
@Test
public void test33() throws Exception {
List stringsOne = new ArrayList<String>();
stringsOne.add("张三");
stringsOne.add(555);
stringsOne.forEach(System.out::println);
//这里不会报错,输出结果为:张三 555
List<String> stringsTwo = new ArrayList();
stringsTwo.add("张三");
stringsTwo.add(555); //这里会报错,表示需要一个String类型,但是给的是int类型
}
既然java的泛型只在编译时起作用那将泛型替换为具体类型时是怎么替换的呢?如果没有指定泛型的上下限只用T来表示泛型那T将会被替换为Object类型,此时理论上任何对象都符合,前提是绕过java的编译检查,例如使用java的反射向List<Integer>中添加字符串:
@Test
public void test34() throws Exception {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(1);
// 获取integers的Class对象
Class<?> aClass = integers.getClass();
// 获取add方法,并在中添加字符串“伍”
Method add = aClass.getMethod("add", Object.class);
add.invoke(integers,"张三");
// 展示
for (int i = 0; i < integers.size(); i++) {
System.out.print(integers.get(i)); //输出是1234伍
}
}
Java的泛型在使用时存在上下限,泛型的父类为下限,子类为上限。
泛型在使用时并不能实例化,这里的使用是指在类中或方法中,泛型是不能实例化的也是因为java的泛型是伪泛型,在运行时并不能知道改类型的具体类型。
参考:
Java 基础 - 泛型机制详解 | Java 全栈知识体系
《深入理解java虚拟机》