6
static <V> void myMethod(Map<?, V> map)
{
 Iterator<Entry<?, V>> it = map.entrySet().iterator();
}

我看到以下编译错误:
类型不匹配:无法转换Iterator<Map.Entry<capture#5-of ?,V>>Iterator<Map.Entry<?,V>>

4

1 回答 1

10

尝试

Iterator<? extends Entry<?, V>> it = map.entrySet().iterator();

您的尝试不起作用的原因有点难以看出,特别是因为Iterator<T>它不消耗任何T东西(即它没有将 aT作为参数的方法)。

您无法将 an 分配给Iterator<Entry<capture#5-of ?,V>>anIterator<Entry<?, V>>的原因与您无法将 an 分配给 an 的原因Iterator<Entry<Integer, String>>相同Iterator<Entry<?, V>>。这capture#5只是一个名称,用于将?方法参数中的特定内容与其他不同的通配符实例区分开来。它可以很容易地成为一个具体的类型。

如果不是Iterator您想到像List.

List<Entry<Integer, String>> entries = new ArrayList<>();

//this is a compile error, but assume it is possible
List<Entry<?, String>> wildcardEntries = entries; 

//then since this is already possible
wilcardEntries.add(new Entry<String, String>("a", "b"));
Entry<Integer, String> entry1 = entries.get(0);

//this would result in a type error (ClassCastException)
Integer i = entry1.getKey();

通过使用? extends Entry<?, V>,您不会暴露自己,因为您不声称知道EntryIterator可以消费的类型,只知道它可以生产什么。

编辑

尽管 Jiman 删除了他的答案,但他有一个很好的观点,即使用 for-each 循环是一种更简洁的方法(假设您只是试图遍历条目),可以完全避免这个问题。这应该有效:

for ( Entry<?, V> entry : map.entrySet() ) {
   //...
}
于 2012-11-10T07:14:46.083 回答