接下来是this question,它提供了一个解决方案,但没有解释它(不幸的是,答案中的链接现在已经死了):
采取以下方法:
void method(Map<?, ?> myMap) {
Set<Map.Entry<?, ?>> set = myMap.entrySet();
...
}简单,不是吗?但是,这不能在jdk1.7.0_25上编译:
所需的不兼容类型: java.util.Set found: java.util.Set>
WTF?Map.entrySet()被指定为返回类型为Set<Map.Entry<K, V>>的对象,因此在上面的示例中,myMap.entrySet()返回一个Set<Map.Entry<?, ?>>。但它不编译!
更奇怪的是,从顶部的链接问题来看,将方法改为此方法使其能够编译:
void method(Map<?, ?> myMap) {
Set<? extends Map.Entry<?, ?>> set = myMap.entrySet();
...
}WTF?在Map<?, ?>上调用entrySet返回一个Set<Map.Entry<K, V>>,该Set<Map.Entry<K, V>>不能分配给Set<Map.Entry<K, V>>类型的变量,但可以分配给Set<? extends Map.Entry<K, V>>?类型的变量。
有人能弄清楚这是怎么回事吗?这是否意味着,每当我使用通配符类型编写至少2层深度的方法时,必须记住在某个地方使用? extends ...?
发布于 2013-11-01 13:13:08
其中的每一个?可以独立变化,因此不能保证myMap声明中的<?,?>与set声明中的<?,?>匹配。
这意味着,一旦我有了一个Set<Map<?,?>>,我就可以将任何类型的Map放到这个集合中,因为Map<?,?>是所有类型Map的超级类型。但这并不是Set<Map<String,Integer>> (例如)所拥有的属性--就我可以放入的映射类型而言,它的限制性要大得多。因此,Set<Map<?,?>>不是Set<Map<String,Integer>>的超级类型。但myMap.entrySet()很容易成为Set<Map<String,Integer>>,这取决于myMap是什么。所以编译器必须禁止我们将它分配给Set<Map<?,?>>类型的变量,这就是正在发生的事情。
另一方面,Set<? extends Map<?,?>>是Set<Map<String,Integer>>的超级类型,因为Map<String,Integer>是Map<?,?>的子类型。因此,可以将myMap.entrySet()赋值给Set<? extends Map<?,?>>类型的变量。
请注意,String和Integer没有什么特别之处,但是myMap必须是某种东西的地图!
你可以写
<K, V> void method(Map<K, V> myMap) {
Set<Map.Entry<K, V>> set = myMap.entrySet();
...https://stackoverflow.com/questions/19727396
复制相似问题