2013-10-13 68 views
4

首先是泛型的新功能。現在的問題 - 在HashMap.java我看到以下內容 -HashMap中的泛型不似乎一致地使用

transient Entry[] table; 
which is initiated in constructor as 
table = new Entry[capacity]; 

爲什麼不用類型參數聲明?

或者

private V getForNullKey() { 
     for (Entry<K,V> e = table[0]; e != null; e = e.next) { 

爲什麼進入for循環使用類型參數聲明?

有沒有一個深刻的概念或只是一個負擔得起的不一致?

回答

7

這是因爲創建一個具體的參數化類型的數組不是類型安全的,這就是爲什麼這是不允許的。

如果你嘗試代碼這樣的事情,你會得到一個編譯錯誤:

List<String>[] arr = new ArrayList<String>[10]; // Compiler error: Generic Array creation 

的問題是,通用的類型是non-reifiable - 它們的類型信息不是在運行時可用。同時,數組使用在運行時可用的類型信息來執行ArrayStoreCheck以查看插入到數組中的元素是否與數組的類型兼容。所以,如果你混淆了數組和泛型,那麼你可能會在運行時產生令人驚訝的行爲。

例如,請考慮下面的代碼:

List<String>[] arr = new ArrayList<String>[10]; // Suppose this was valid 
Object[] objArr = arr;   // This is valid assignment. A `List[]` is an `Object[]` 
objArr[0] = new ArrayList<Integer>(); // There you go. A disaster waiting at runtime. 

String str = arr[0].get(0); // Assigned an `Integer` to a `String`. ClassCastException 

所以,有編制的第一個任務,第四次分配,這看起來不錯的編譯器,將不得不在運行時拋出ClassCastException


但是,您可以創建原始類型的數組 - ArrayList,或者無界通配符參數化類型 - ArrayList<?>,因爲他們兩人都是完全reifiable類型。所以下面的陣列創作是有效的:

List[] arr = new ArrayList[10]; 
List<?>[] arr2 = new ArrayList<?>[10]; 

由於沒有與原始類型或無界通配符類型相關聯的任何類型的信息,有沒有在運行時丟失。因此,這些類型是可確定的,它們是數組的合格組件類型。這就是爲什麼使用Entry[]而不是Entry<K, V>[]


參見:

+0

巨大的感謝和祝賀爲60K – JavaDeveloper

+0

@JavaDeveloper我們歡迎並感謝:) –

相關問題