1

如果我定义了Map<K,V> map = new HashMap<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);  
}  
4

3 回答 3

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其用作键 (the K) 和SomeOtherObject值 (the V) 的类型。所以你需要为这些类型创建一个特定的地图:Map<MyKey,SomeOtherObject> map = new HashMap<MyKey, SomeOtherObject>();.

你不能简单地写Map<K, V>,因为 K 和 V 对编译器没有任何意义(除非你创建了一个名为 K 的类和一个名为 V 的类,但我假设你没有)。

在你的第二个例子中,你使用了一个泛型方法,它接受两个类型为 K 和 V 的参数。当调用该方法时,K 和 V 被接收到的实际类型替换,所以你的例子中的代码被转换为非常类似于我答案顶部的代码。

我希望这可以澄清事情。我建议您花时间阅读有关泛型的教程并查看具体示例。

于 2012-09-14T11:31:12.953 回答
1

这不是它的工作方式:类是通用的,但实例必须是特定的。

您指定您的地图在实例化时可用的类:

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

如果你想要一个完全通用的实例,你会使用这个:

Map myMap = new HashMap();

那是......没有“泛型”。

于 2012-09-14T11:30:10.573 回答
0

正如其他答案中提到的那样,实例必须具体说明 K 和 V 是什么(这是泛型的重点 - 如果您希望能够添加任何您想要的内容,您只需使用Map不带泛型的 a,或Map<Object, Object>)。但是,要能够添加多个自定义类,您可以做的是让它们都扩展一个基类并将 Map 设置为Map<MyKeyBaseClass, MyValueBaseClass>. 如果键或值可以是任何东西,请Object改用。如果您认为泛型的目的实际上是缩小您接受的对象的范围,而不是扩大范围,您可能会发现它更容易。

编辑:您似乎对泛型的基本原则有一些困难,我建议您阅读Java 泛型教程

于 2012-09-14T11:34:57.437 回答