当前位置: 首页 > 知识库问答 >
问题:

与有界通配符相关的编译器错误

邹修真
2023-03-14
Map <? extends String, ? extends Integer> m = null;
Set<Map.Entry<? extends String, ? extends Integer>> s = m.entrySet();

s的类型应该是什么?Eclipse建议使用set<?>,但我试图获得更具体的信息。

共有1个答案

陆建木
2023-03-14

这个问题在这个旧的Apache线程中解决:

问题是entrySet()方法返回的是set > 与类型 > 。如果我删除extendskextendsv部分,就更容易描述为什么。因此,我们有

第一个set 是一组不同类型的map.entry-即它是一个异构集合。它可以包含一个map.entry 和一个map.entry > 以及任何其他类型对,它们都在同一个集合中。

另一方面,set > 是相同(尽管未知)类型对的同质集合。例如,它可能是set ,因此集合中的所有条目都必须是map.entry

问题的关键是顶级通配符捕获,这意味着它们本质上是一次性类型参数。相反,嵌套通配符不能捕获,并且有一些不同的含义。

因此,为了简单起见,删除边界,声明

Map<?, ?> m;
Set<Map.Entry<?, ?>> s;

一种解决方法是使用捕获帮助器方法,它利用了可以嵌套形式类型参数的事实:

private <K extends String, V extends Integer> void help(final Map<K, V> map) {
    final Set<Map.Entry<K, V>> entries = map.entrySet();
    // logic
}

...

Map<? extends String, ? extends Integer> m = null;
help(m);

这是一个虚构的示例,因为stringinteger都是final,但它展示了概念。

下面是一个更简单的解决方法:

Set<? extends Map.Entry<? extends String, ? extends Integer>> s = m.entrySet();
 类似资料:
  • 考虑以下示例: 我知道下界通配符接受通配符中给定类的所有超类(这里是IOException)。 为什么在上述情况下编译器会显示编译错误?

  • 我不明白为什么会出现这些编译错误: 1: 类型列表中的add(capture#1-of?extends Exec.Bird)方法不适用于参数(Exec.Sparrow) 2: 方法添加(捕获#2-of?扩展Exec.Bird)类型列表中的参数(Exec.鸟)

  • 当构造函数参数使用 val 声明时,下面的代码失败 作品: 不工作: 编译器给出错误: Scala编译器中的错误:类型不匹配;找到:java.lang.Object必需:array[java.lang.Object] 而不能给出行号。

  • null 为什么我不能在MyList中添加对象。因为如果我们使用super,这意味着这个列表可以包含在Java类的继承制度中等于或高于number的对象。因此应该按照该语句在列表中添加新的Object()。 多谢了。

  • 我将repo.scala-sbt.org和dl.bintray.com证书添加到Java密钥库中,并将密钥库路径(djavax.net.ssl.truststore)添加到sbt配置中,但这并不能解决问题。有什么解决这个问题的建议吗? --TIA -djavax.net.ssl.trustStore=“\jre\lib\security\cacerts” [error](更新)LMCoursier

  • 主要内容:1) 源文件(Source File),2) 工程/项目(Project),3) 工程类型/项目类型,4) 链接(Link)上节我们介绍了编译器和 IDE 的概念,大家肯定希望赶紧实践一下,用 IDE 真正地运行一段C语言代码来看看效果,这样能够更快地获得成就感。 但是,使用 IDE 的过程中会涉及到一些与编程有关的概念,这些概念如果不提前了解,即使能够运行出程序来,也是雾里看花,知其然不知其所以然。本节的目标就是让大家对这些概念有一个简单的了解。 1) 源文件(Source File