Java类型捕获集合中的通配符

时间:2012-07-16 21:02:13

标签: java generics collections types

我想这样做(最小的重复):

String key = "foo";
Object value = new Bar();

if (target instanceof Map<?,?>) {
    Map<?,?> map = (Map<?,?>)target;
    map.put(key, value);
    ...

但我被告知:

  

该方法在类型中放置(捕获#25-of?,捕获#26-of?)   地图不适用于   arguments(String,Object)

看起来String和Object在这里都应该没问题。我的问题有两个部分:(1)为什么? (2)我怎样才能做出类似这样的工作?

3 个答案:

答案 0 :(得分:1)

问题是使用无界通配符的集合不允许将元素添加到它们中。如果他们这样做了,您可以将集合转换为具有更具体的类型参数,并且突然间泛型应该提供的类型安全性已经消失:

Map<?,?> map = (Map<?,?>)target;
map.put(key, value);  // Not actually allowed
Map<String, String> evilMap = (Map<String, String>)map;
String barAsString = evilMap.get(key); // But it's actually a Bar!

答案 1 :(得分:1)

地图&lt;?,?&gt;真的意思是,Map&lt;? extends Object,? extends Object&gt;根据Java类型系统,你只能获得专门用于的类型参数的值?从方法调用扩展通配符。你无法将它传递给方法。

P.S。可能你想要Map&lt; Object,Object&gt;

答案 2 :(得分:0)

This blog post提供了答案。简而言之,编译器不知道Map<?, ?>是否真的是Map<String, Object>,或者说Map<Integer, Double>,所以它不能保证您的类型安全。