如果我定义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);
}
答案 0 :(得分: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将被接收的实际类型替换,因此示例中的代码将被转换与我的答案顶部的代码非常相似。
我希望这能澄清事情。我建议您花时间阅读关于泛型的教程并查看具体的例子。
答案 1 :(得分:1)
这不是它的工作方式:该类是通用的,但实例必须是特定的。
您可以在实例中指定地图可用的类:
Map<SomeClass, SomeOtherClass> myMap = new HashMap<SomeClass, SomeOtherClass>();
如果你想要一个完全通用的实例,你可以使用它:
Map myMap = new HashMap();
那是......没有“泛型”。
答案 2 :(得分:0)
正如其他答案中所提到的,实例必须具体说明K和V是什么(这是泛型的要点 - 如果你想能够添加你想要的任何东西,你只需要使用{ {1}}没有通用,或Map
)。但是,为了能够添加多个自定义类,您可以做的是让它们都扩展基类并使Map为Map<Object, Object>
。如果键或值可以是任何值,则只需使用Map<MyKeyBaseClass, MyValueBaseClass>
。如果您认为泛型的目的实际上是缩小您接受的对象的范围而不是扩大它的范围,您可能会发现它更容易。
编辑:看来你对泛型的基本原则有些困难,我建议你阅读Java tutorial on generics。