JAVA 泛型-类型擦除

概述

Java的泛型是 伪泛型,这是因为Java在 编译期间,所有的泛型信息都会被 擦除 (type erasure)

类型擦除

Java的泛型基本上都是在编译器这个层次上实现的,在生成的 字节码文件(.class) 中是 不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为 类型擦除。

如在代码中定义List<Object>和List<String>等类型,在编译后都会变成List,JVM看到的只是List,而由泛型附加的类型信息对JVM是看不到的。

Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法在运行时刻出现的类型转换异常的情况

类型擦除也是 Java的泛型 与 C++模板机制 实现方式之间的重要区别。

反编译

现在的反编译工具比较智能,可以通过 .class 文件中的信息,推断出泛型

如果反编译工具简单,反编译 .class 文件时,就能发现,没有泛型

例子

//定义list,并有泛型
List<Integer> list=new ArrayList<Integer>();
list.add(1);
//list.add("java");//此行代码编译报错,因为有泛型限制
list.getClass().getMethod("add", Object.class).invoke(list, "java");//通过反射添加,绕过编译检查
for (Object obj:list) {
    System.out.println(obj);
}

原文出处:/show_1EF4tLZmns93.html