Java泛型 – 类型擦除 – 什么时候发生什么

我读了关于Java的类型擦除on Sun’s website

什么时候发生类型擦除?在编译时/运行时?当类加载/运行时?当类实例化时?

很多网站(包括上面提到的Sun教程)说在编译时发生类型擦除。如果类型信息在编译时被完全删除,那么当使用泛型的方法被调用时没有类型信息或错误的类型信息时,JDK检查类型兼容性如何。

考虑下面的例子:说A类有一个方法,为空(Box&lt ;? extends Number> b)。我们编译A.java并获取类文件A.class。

现在我们创建另一个类B,它使用非参数化参数(原始类型) – 空(new Box())调用该方法。如果我们在类路径中使用A.class编译B.java,javac足够聪明,可以产生警告。所以A.class有一些类型信息存储在它。

我的猜测是类型擦除发生在类加载时,但它只是一个猜测。所以什么时候发生?

最佳答案
类型擦除适用于使用泛型。在类文件中肯定有元数据来说明方法/类型是否是通用的,约束是什么等等。但是当使用泛型时,它们被转换为编译时检查和执行时转换。所以这段代码:

List<String> list = new ArrayList<String>();
list.add("Hi");
String x = list.get(0);

编译成

List list = new ArrayList();
list.add("Hi");
String x = (String) list.get(0);

在执行时,没有办法找出T =字符串的列表对象 – 该信息已经走了。

…但是列表< T>接口本身仍然宣告自己是通用的。

编辑:为了说明,编译器保留关于变量的信息,该变量是List< String> – 但是你仍然无法找到列表对象本身的T = String。

转载注明原文:Java泛型 – 类型擦除 – 什么时候发生什么 - 代码日志