2012-09-14 85 views
1

如果我定義了一個Map<K,V> map = new HashMap<K, V>()爲什麼我不能做這樣的事情:K,V有多普遍?

map.put(new MyKey<CustomObject>(), new SomeOtherObject<CustomObject>());

但是,如果我通過其他方法做它的工作原理即:

add(new MyKey<CustomObject>(), new SomeOtherObject<CustomObject>()); 

public <K, V> void add(K k, V v){ 
     Map<K, V> threadLocalMap = new HashMap<K, V>(); 
     threadLocalMap.put(k, v); 
} 

回答

3

您需要顯式聲明在地圖中使用的類型:

Map<MyKey,SomeOtherObject> map = new HashMap<MyKey, SomeOtherObject>(); 
map.put(new MyKey<CustomObject>(), new SomeOtherObject<CustomObject>()); 

在第二個例子中,add方法是通用的,所以當你調用它,K和V所使用的實際類型取代在調用代碼中。

編輯

你似乎誤解了Map<K, V>意義。 K和V沒有任何具體的含義,它們只是表明你可以「將參數化」地圖,只接受某種類型的鍵和某種類型的值。但是您有責任定義這些類型。

在你的第一個例子,你要使用MyKey作爲鍵(在K)和SomeOtherObject的值(V)類型。所以你需要爲這些類型創建一個特定的地圖:Map<MyKey,SomeOtherObject> map = new HashMap<MyKey, SomeOtherObject>();

你不能簡單地寫Map<K, V>,因爲K和V對編譯器沒有任何意義(除非你創建了一個名爲K的類和一個名爲V的類,但是我認爲你沒有)。

在第二個例子中,您使用了一個通用的方法,該方法接受了K和V兩個參數。當調用該方法時,K和V將被接收的實際類型替換,因此示例中的代碼是轉化爲與我答案頂部的代碼非常相似的東西。

我希望這能說明一些事情。我建議你花時間閱讀泛型教程,並看看具體的例子。

+0

查看更新OP – Jim

+0

@Jim剛剛編輯。 – assylias

+0

所以你說這是一個替代'K'和'V'的工作區? – Jim

1

這不是它的工作原理:該類是通用的,但實例必須具體。

指定由哪個地圖是在instanciation可用類:

Map<SomeClass, SomeOtherClass> myMap = new HashMap<SomeClass, SomeOtherClass>(); 

如果你想要一個完全通用的情況下,你會使用這樣的:

Map myMap = new HashMap(); 

也就是說。 ..沒有「泛型」。

+0

查看OP – Jim

+0

的更新在你工作的代碼中,你只是按照我描述的創建實例,所以沒有理由不工作,你只是以參數化的方式做,但因爲你不是使用尚未創建的地圖,它幾乎是無用的:您無法將其應用於現有的參數化地圖。 –

0

正如其他答案中所提到的,實例必須具體說明K和V是什麼(這是泛型的一點 - 如果您希望能夠添加所需的任何內容,只需使用沒有泛型的MapMap<Object, Object>)。然而,你可以做什麼來添加多個自定義類是讓它們都擴展一個基類,並讓Map成爲Map<MyKeyBaseClass, MyValueBaseClass>。如果鍵或值可以是任何值,只需使用Object。如果您認爲泛型的目的實際上是縮小您接受的對象的範圍而不是擴大它,您可能會發現它更容易。

編輯:看來你對泛型的基本原理有一些困難,我會推薦閱讀Java tutorial on generics

相關問題