2012-06-30 81 views
1

在下面的代码片段中,为什么1不会生成运行时异常,因为我试图将Class> B>转换为Class> A>?Class Literal vs Class.forname + Java Generics

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 
} 
+1

它*可能*抛出一个ClassNotFoundException。有了这种异常处理,你永远不会知道。 – EJP

+0

哦,其实我已经在打印内打印了,只是忘了在我的问题中添加它。放心吧,没有ClassNotFoundException –

回答

3

Class.forName()返回Class<?>,大致相当于Class(没有泛型)。

c = (Class<A>)(Class) B.class; // compiles 

然而,这不可能是正确的,所以编译器从这一错误中节省您:如果您添加其他非通用铸其间

第二个版本也将编译。在第一个版本中,它不能这样做。

1

因为泛型只能由编译器而不是java虚拟机执行。你可以这样想,在编译期间由编译器清除。 Java泛型以这种方式实现,以便与早期Java版本向后兼容。

1

Java泛型通过擦除来实现,这意味着泛型在编译时被检查,但在运行时不可用。这使得带有泛型的java代码可以与前1.5代码向后兼容。