问题描述
继续从,它提供了一个解决方案,但没有解释它(不幸的是,答案中的链接现在已经失效):
采取以下方法:
超类型 Set< Map< String,Integer>> ,因为 Map< String,Integer> 是 Map的子类型 。因此,将 myMap.entrySet()分配给 Set 类型的变量是可以的。扩展Map >< / code>。
请注意, String 和 Integer 在这里,但是 myMap 必须是的地图!
您可以写下:
< K,V> void方法(Map< K,V> myMap){
Set< Map.Entry< K,V>> set = myMap.entrySet();
...
Following on from this question, which provides a solution but doesn't explain it (unfortunately, the links in the answers are now dead):
Take the following method:
void method(Map<?, ?> myMap) { Set<Map.Entry<?, ?>> set = myMap.entrySet(); ... }Simple, no? However, this fails to compile on jdk1.7.0_25:
WTF? Map.entrySet() is specified as returning an object of type Set<Map.Entry<K, V>>, so in the example above, myMap.entrySet() returns a Set<Map.Entry<?, ?>>. But it doesn't compile!
Even weirder, from the linked question at the top, changing the method to this makes it compile:
void method(Map<?, ?> myMap) { Set<? extends Map.Entry<?, ?>> set = myMap.entrySet(); ... }WTF??? Calling entrySet on a Map<?, ?> returns a Set<Map.Entry<K, V>>, which can't be assigned to a variable of type Set<Map.Entry<K, V>>, but it can to a variable of type Set<? extends Map.Entry<K, V>>?????
Can anyone shed light on what's going on here? And does this mean that, whenever I write a method using a wildcard type at least 2 levels deep, I have to remember to make it ? extends ... somewhere?
解决方案Each of those ? can vary independently, so there's no guarantee that the <?,?> in the declaration of myMap matches the <?,?> in the declaration of set.
What this means is that once I have a Set<Map<?,?>>, I can put any type of Map into that set, because Map<?,?> is a supertype of all types of Map. But this is not a property that Set<Map<String,Integer>> (for example) has - it's far more restrictive in terms of what types of map I can put into it. So Set<Map<?,?>> is not a supertype of Set<Map<String,Integer>>. But myMap.entrySet() could easily be a Set<Map<String,Integer>>, depending on what myMap is. So the compiler has to forbid us from assigning it to a variable of type Set<Map<?,?>>, and that's what's happening.
On the other hand, Set<? extends Map<?,?>> is a supertype of Set<Map<String,Integer>>, because Map<String,Integer> is a subtype of Map<?,?>. So it's OK to assign myMap.entrySet() to a variable of type Set<? extends Map<?,?>>.
Note that there's nothing special about String and Integer here, but myMap has to be a map of something!
You could write
<K, V> void method(Map<K, V> myMap) { Set<Map.Entry<K, V>> set = myMap.entrySet(); ...
这篇关于不兼容的通配符类型应该兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!