我在Oracle网站上了解了Java的类型擦除。
什么时候出现类型擦除?在编译时还是在运行时?该类何时加载?该类何时实例化?
许多站点(包括上面提到的官方教程)都说类型擦除在编译时发生。如果在编译时完全删除了类型信息,那么在没有类型信息或错误类型信息的情况下调用使用泛型的方法时,JDK如何检查类型兼容性?
考虑以下示例:说说类A
有一个方法empty(Box<? extends Number> b)
。我们编译A.java
并获得类文件A.class
。
public class A {
public static void empty(Box<? extends Number> b) {}
}
public class Box<T> {}
现在,我们创建另一个类B
,该类empty
使用非参数化参数(原始类型)调用该方法:empty(new Box())
。如果我们编译B.java
与A.class
在类路径中,javac的是足够聪明提出一个警告。因此A.class
,其中存储了一些类型信息。
public class B {
public static void invoke() {
// java: unchecked method invocation:
// method empty in class A is applied to given types
// required: Box<? extends java.lang.Number>
// found: Box
// java: unchecked conversion
// required: Box<? extends java.lang.Number>
// found: Box
A.empty(new Box());
}
}
我的猜测是在加载类时会发生类型擦除,但这只是一个猜测。那么什么时候发生呢?