2013-04-07 74 views
2

假設有兩個類別,即PetDogPet類是Dog類的超類。爲什麼不能Class.getSuperClass()方法得到完全的超類類型實例?

Ques01:

當我編碼如下,發生編譯錯誤:Type mismatch: cannot convert from Class<capture#2-of ? super Dog> to Class<Pet>

Class<Pet> c1 = Dog.class.getSuperclass(); 

它是這樣的:

Class<? super Dog> c2 = Dog.class.getSuperclass(); 

此外,當我使用c2.newInstance(),它只返回一個Object實例。爲什麼我不能只獲得class PetClass Instance

Ques02:

當我的System.out的c2.getName(),它輸出"pet"!所以c2剛剛得到了我想要的信息。

我真的很困惑這些。任何人都可以提供幫助嗎?非常感謝!

回答

1

Java中的反射API比泛型要古老得多。 RTTI中的一些方法反映了這一點。

此外,RTTI是運行時功能和泛型是彙編功能。有時,編譯器只是沒有足夠的信息來檢查運行時類型是否正確。

但是,例如,您的newInstance示例無效。

public class Test { 
    class Pet {} 

    class Dog extends Pet {} 

    public static void main(String[] args) throws Exception { 
     Class<Dog> dogClass = Dog.class; 
     Dog dog = dogClass.newInstance(); 
    } 
} 

編譯沒有問題,因爲在Class<T>方法聲明爲T newInstance()

如果我們把getSuperClass()例子,你必須先了解編譯器不知道什麼getSuperClass()一樣。它只看方法聲明。這就是爲什麼它不知道返回的課程真的是Pet。它只是比較變量的類型和由getSuperClass返回的對象的類型。變量是Class<Pet>,返回的對象是Class<? super Dog>,這是不一樣的。編譯器不會模擬getSuperClass實現,也不知道返回的確切對象。

+0

是的,我知道這個例子可以使用'newInstance'方法。我只是對'getSuperclass()'返回的Class實例感到困惑。由於我剛剛獲得了一個'類 c2',它可以創建一個Object實例,同時'c2.getName()'表示它確實代表一個'Pet Class'。那麼如何使用c2獲得Class 實例?非常感謝。 – Judking 2013-04-07 13:46:40

+0

@Judking當然可以。編譯器不知道它。用''方法必須返回'Object',因爲它也是'T'的超類。 – Sulthan 2013-04-07 13:53:03

0

問題太多成一個職位....

這裏的一般答案是傳統和向後兼容性。泛型已經在1.5版本中引入了Java。方法getSuperClass()從1.0版本開始就存在於java中。 Java創作者不能破壞舊版本的兼容性,所以他們沒有改變它的原型。這就是爲什麼你必須投Dog.class.getSuperclass();Class<? super Dog>或類似的東西。

同樣是關於newInstance(),不幸的是它返回普通對象,而它創建「正確」的實例。所以你也必須在這種情況下投。因此getName()返回正確的班級名稱:班級確實是Pet

+1

這是錯誤的,'newInstance()'返回類型'T','getSuperClass()'返回'類'。 – Keppil 2013-04-07 13:30:26

+0

非常感謝! – Judking 2013-04-07 14:01:05

相關問題