我在http://download.oracle.com/javase/tutorial/java/generics/erasure.html处理了TypeErasure主题,该主题说编译器会删除与类参数相关的所有信息,并在类或方法中输入类型参数 .
现在考虑下面的代码
public class Box<T> {
private T t; // lineA, T stands for "Type"
public void add(T t) { // lineB
this.t = t; // lineC
}
public T get() { // lineD
return t; // lineE
}
}
现在在 main
方法中我有下面的代码片段
Box<String> box1 = new Box<String>(); // line1
box1.add("Scott"); // line2
String s1tr=box1.get(); // line3
Box<Integer> box2 = new Box<Integer>(); // line4
box2.add(1); // line5
Integer k=box2.get(); // line6
现在在上面的代码中(在 Box
类和 main
方法中)编译器将进行哪些更改以及在哪一行?
由于链接说编译器删除了与类或参数中的类型参数和类型参数相关的所有信息,当编译器将编译 Box
类时,它是否会分别从 Box
类和 main
方法中删除所有 T
, <String>
, <Integer>
出现?如果是,删除 T
后编译的代码是什么?
2 回答
类型擦除发生在编译时 . Java编译器从源中删除这些泛型类型信息,并根据需要添加强制转换并提供字节代码 . 因此,生成的字节代码将不包含有关类型参数和参数的任何信息 . It will look like a old java code without generics. 无法在运行时确定T的值,因为在编译代码之前会删除该信息 .
如果没有像示例代码中那样的类型边界,那么(大致)会发生在Box类中,方法代码中对
T
的所有引用的所有实例都将被Object替换 . 在使用Box类的代码中,将删除<String>
,<Integer>
等所有实例 .关于Java Generics的详尽深入的文章是Angelika Langer's FAQ - 它还解释了类型边界的影响等等 .