2013-08-21 68 views
2

爲什麼編譯器不會產生任何錯誤?在JLS中,我可以瞭解這種情況?使用泛型類時沒有錯誤,而沒有定義類型

class Main { 
    public static void main(String[] args) { 
    A a = new A(); 

    List<Integer> list = a.getStrings(); 
    } 

    static class A<X> { 
    public List<String> getStrings() { 
     return new ArrayList<String>(); 
    } 
    } 
} 
+0

此代碼執行(沒有錯誤)或只編譯? – Dennis

+3

我最近看到了這個問題。基本上,在不使用類型參數的情況下使用'A'的時候,編譯器就好像'A'中沒有使用泛型一樣。這是一個向後兼容的東西。 –

+0

您正在使用原始'A'類,這對向後兼容性沒有錯誤 –

回答

5

您可以瞭解這個情況在JLS §4.8

使用原始類型只允許作爲讓步的遺留代碼的兼容性。強烈建議在將泛型引入Java編程語言之後編寫的代碼中使用原始類型。未來版本的Java編程語言可能會禁止使用原始類型。

爲確保始終標記可能違反打字規則的行爲,對原始類型成員的某些訪問將導致編譯時未經檢查的警告。用於訪問成員或原始類型的構造時編譯時未檢查警告的規則如下:

  • 在一個分配給一個字段:如果左手操作數的類型是原始類型,則如果擦除更改字段的類型,則會發生編譯時未檢查警告。

  • 在調用方法或構造方法時:如果要搜索的類或接口的類型(第15.12.1節)是原始類型,那麼如果擦除更改任何正式方法,則會發生編譯時未檢查警告方法或構造函數的參數類型。

  • 當形式參數類型在擦除時不發生更改(即使結果類型和/或拋出子句發生更改),從字段或類讀取時,對於方法調用不會發生編譯時未經檢查的警告實例創建一個原始類型。

2

這就是所謂的使用原始類型。因爲泛型並不總是Java的一部分,所以這是出於遺留原因的語言。

而且由於您不使用泛型類型參數,它只是被擦除。正如評論者所指出的那樣如果你在類型擦除之後沒有指定一個類型參數,它將是一個Object

+0

當泛型沒有明確指定時,我認爲它默認爲'Object' –

相關問題