在下面的代码片段中,为什么1不会产生运行时异常,因为我正在尝试强制转换Class> B>到班级> A>?
package example;
Class A {
public A() {
}
}
Class B extends A {
public B() {
}
}
public static void main() {
Class<A> c = null;
//1. Does not produce exception at run-time even though I cast Class<B> to Class<A>
try {
c = (Class<A>) Class.forName("example.B");
} catch (ClassNotFoundException e) {
}
//2. Compile time error: Cannot Cast Class<B> to Class<A>
c = (Class<A>) B.class; //Error
}
答案 0 :(得分:3)
Class.forName()
返回Class<?>
,大致相当于Class
(没有泛型)。
如果你在中间添加另一个非通用的强制转换,第二个版本也会编译:
c = (Class<A>)(Class) B.class; // compiles
但是,这可能不对,因此编译器可以避免此错误。在第一个版本中,它无法做到这一点。
答案 1 :(得分:1)
因为泛型只是由编译器强制执行而不是java虚拟机。您可以这样思考,在编译期间由编译器清除。 Java泛型以这种方式实现,以便与早期的Java版本向后兼容。
答案 2 :(得分:1)
Java泛型是通过擦除实现的,这意味着在编译时检查泛型,但在运行时不可用。这允许带有泛型的java代码向后兼容1.5之前的代码。