2012-06-30 48 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代碼向後兼容。