Java 泛型类型擦除:何时发生以及会发生什么?
我在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> {}
现在我们创建另一个类,该类使用非参数化参数(原始类型)调用方法:。如果我们在类路径中使用编译,javac 足够聪明,可以发出警告。因此,其中存储了一些类型信息。B
empty
empty(new Box())
B.java
A.class
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());
}
}
我的猜测是,类型擦除发生在加载类时,但这只是一个猜测。那么它什么时候会发生呢?