我有以下情况:在下面的代码中,方法foo
编译,而方法bar
不编译。在方法调用entrySet
(在代码中表示)时,编译器说:
Type mismatch: cannot convert
from Set<Map.Entry<capture#1-of ? extends K,capture#2-of ? extends V>>
to Set<Map.Entry<? extends K,? extends V>>
有趣的是,Eclipse的quickfix建议
Change type of 's' to Set<Entry<? extends K, ? extends V>>
它只会更改代码,因为快速修复程序忽略了自己的建议,而是将s
类型改为Set<?>
。
我正在使用JDK1.8.0_51和Eclipse4.4.0。也许这与通配符或捕获有关?如有任何帮助或建议,将不胜感激。提前感谢!
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MyClass<K, V> {
public void foo(Set<Entry<? extends K, ? extends V>> set) {
Iterator<Entry<? extends K, ? extends V>> i = set.iterator();
}
public void bar(Map<? extends K, ? extends V> map) {
Set<Entry<? extends K, ? extends V>> s = map.entrySet();
^^^^^^^^^^^^^^
}
}
发布于 2015-08-21 15:59:37
简单的回答是,如果以问题中的方式声明集合,就可以添加不符合传递给方法的对象类型的条目。Java没有保留足够的信息来检查集合定义中的“扩展K”是否与方法参数中的“扩展K”相同。
为了避免这种情况,Java要求您将赋值声明为:
Set<? extends Map.Entry<? extends K,? extends V>> s = map.entrySet();
..。你会发现你不能添加你自己的条目到这个集合-至少,不是没有做很多坏的转换,这将产生很多警告。
正如上面所提到的,这个问题更详细地涵盖了这个主题:Generic Iterator on Entry Set
发布于 2015-08-21 15:26:40
假设K和V是数。声明没有将与映射一起传递的类型链接到条目集中使用的类型。虽然我们知道这是不可能发生的,但是如果map是一个Map<Integer,Integer>
,那么声明允许s是一个Set<Entry<Double,Double>>
,因为它仍然扩展了数字。
因此,如果您明确表示这些类型匹配,请编写以下内容:
public <K0 extends K, V0 extends V> void bar(Map<K0,V0> map) {
Set<Entry<K0,V0>> s = map.entrySet();
}
您的意思很明确,“s”的类型将与“map”的类型完全匹配。因此,它可以快乐地编译。
https://stackoverflow.com/questions/32143844
复制相似问题