2014-02-28 125 views
2

我第一次使用EnumMap,並不明白參數傳遞實際上在做什麼。據我所知它只是「K.class」,其中K是地圖鍵。這工作得很好,但我在Java中沒有見過其他任何地方,我不清楚它在構建中實際扮演什麼角色。Java EnumMap參數混淆

我想這是一個理論問題,因爲代碼運行:「K.class」參數意味着什麼,EnumMap需要什麼?

+2

[什麼是Java中的類文字?](http://stackoverflow.com/questions/2160788/what-is-a-class-literal-in-java) –

+0

什麼部分你不完全明白嗎? – fge

+2

''將在編譯器應用類型刪除之後從'Map '中消失。但是,在運行時'Map'實現需要確切地知道你在說什麼枚舉類。所以你必須指定類。 –

回答

7

查看關聯問題class literals

EnumMap特別需要它,因爲它需要知道enum有多少個不同的值。這是因爲EnumMap是一種針對枚舉的高度優化的映射實現,對於每個可能的值,只使用一個具有一個插槽的陣列(而不是像HashMap那樣的更大的陣列)。當您調用get()時,它將檢索給定鍵的索引(即第一個枚舉值,第二個枚舉值等),並查找其內部數組的適當位置。爲此,構造函數需要知道可能的值的數量來分配正確大小的數組。 給定類對象,它可以調用getEnumConstants()來找出此枚舉的現有值的數量。

此外,想象下面的代碼:

enum Enum1 { V1, V2; } 
enum Enum2 { W1, W2; } 
EnumMap<Enum1, Object> map = new EnumMap<Enum1, Object>(Enum1.class); 
map.put(Enum1.V1, new Object()); 
map.get(Enum2.W1); 

現在get方法顯然應該返回null。但是,正如我所說的,映射內部只有一個數組,在這種情況下大小爲2,新對象位於第一個槽中,而第二個位置爲null。當您將它傳遞給put()時,它沒有存儲對Enum1.V1的引用。但是,方法get現在需要知道傳遞的值不屬於正確的枚舉,因此映射中沒有該鍵的值。這裏也需要正確的枚舉類型,爲此需要將類型傳遞給構造函數。如果沒有你提供關於構造函數的枚舉的一些信息,它不知道你想使用這個映射實例的枚舉。即使您編寫新的EnumMap<MyEnum, SomeValue>(),由於類型擦除,構造函數也不知道泛型類型參數的值MyEnum。因此,需要另一種方式將信息傳遞給構造函數。

+1

謝謝你,我現在跟着。我對泛型很熟悉,這意味着其他許多其他評論和討論都無濟於事。我只是偶爾熟悉類文字,所以我不明白是否需要使用類文字,因爲我沒有考慮過這種類型的刪除操作不能防止檢查鍵類型。 – wintermute92

1

根據EnumMap的來源:看起來,當你構造一個EnumMap時,它所做的第一件事就是分配一個數組,其中每個枚舉常量在enum類中都有一個枚舉常量。 EnumMap應該是有效的,所以它是有道理的,它將分配一個固定的數組。要做到這一點,它需要知道這個班。如果不是用於類型擦除,可以通過查看K.class來完成,其中KEnumMap<K,V>中的第一個類型參數。不幸的是,Java泛型的設計阻止了這一點。

+0

在查看實現之前,應首先檢查規範。它說「枚舉映射在內部表示爲數組」。 –