首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应该兼容的不兼容通配符类型

应该兼容的不兼容通配符类型
EN

Stack Overflow用户
提问于 2013-11-01 13:08:42
回答 1查看 2.2K关注 0票数 3

接下来是this question,它提供了一个解决方案,但没有解释它(不幸的是,答案中的链接现在已经死了):

采取以下方法:

代码语言:javascript
复制
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<?, ?>>。但它不编译!

更奇怪的是,从顶部的链接问题来看,将方法改为此方法使其能够编译:

代码语言:javascript
复制
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 ...

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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<?,?>>类型的变量。

请注意,StringInteger没有什么特别之处,但是myMap必须是某种东西的地图!

你可以写

代码语言:javascript
复制
<K, V> void method(Map<K, V> myMap) {
    Set<Map.Entry<K, V>> set = myMap.entrySet();
    ...
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19727396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档