【问题标题】:Type mismatch when using Map.entrySet()使用 Map.entrySet() 时类型不匹配
【发布时间】:2015-11-15 14:33:32
【问题描述】:

我有以下情况:在下面的代码中,方法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>>

这只会更改代码,因为 quickfix 忽略了自己的提议,而是将 s 的类型更改为 Set&lt;?&gt;

我正在使用 JDK1.8.0_51 和 Eclipse 4.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();
                                                 ^^^^^^^^^^^^^^
    }
}

【问题讨论】:

  • Intellij 建议:Set&lt;? extends Map.Entry&lt;? extends K, ? extends V&gt;&gt; s = ... 并且 oracle jdk8 接受了
  • 查看stackoverflow.com/questions/13320105/…的解释。你的例子很相似。

标签: java eclipse generics capture type-mismatch


【解决方案1】:

假设 K 和 V 是数字。该声明没有将通过映射传入的类型链接到条目集中使用的类型。虽然我们知道它永远不会发生,但如果 map 是 Map&lt;Integer,Integer&gt;,那么声明允许 s 是 Set&lt;Entry&lt;Double,Double&gt;&gt;,因为它仍然扩展 Number。

因此,如果您明确表示这些类型匹配,请编写以下代码:

public <K0 extends K, V0 extends V> void bar(Map<K0,V0> map) {
    Set<Entry<K0,V0>> s = map.entrySet();
}

您的意思很明确,“s”的类型将与“map”的类型完全匹配。因此它编译得很愉快。

【讨论】:

    【解决方案2】:

    简短的回答是,如果您按照问题中的方式声明 Set,则可以向其中添加不符合传入方法的对象类型的条目。 Java 没有保留足够的信息来检查 Set 定义中的“? extends K”是否与方法参数中的“? extends K”相同。

    为避免这种情况,Java 要求您将赋值声明为:

    Set<? extends Map.Entry<? extends K,? extends V>> s = map.entrySet();
    

    ...你会发现你不能将你自己的条目添加到这个集合中——至少,如果没有做很多错误的转换,这会产生很多警告。

    正如上面提到的,这个问题更详细地涵盖了这个主题:Generic Iterator on Entry Set

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多