【问题标题】:Surprising "inferred type does not conform to upper bound" error令人惊讶的“推断类型不符合上限”错误
【发布时间】:2019-04-25 03:05:49
【问题描述】:

当我尝试使用 JDK 9、10 或 11 的编译器编译这个精简示例时:

public class UpperBounder {
    public static void main(String[] args) {
        print(Stream.of("a", "z", "b").collect(Collectors.toCollection(TreeSet::new)));
    }

    static void print(Set<?> set) {
        System.out.println(set);
    }
}

我收到此错误:

错误:不兼容的类型:推断的类型不符合上限

print(Stream.of("a", "z", "b").collect(Collectors.toCollection(TreeSet::new)));
^

推断:INT#1
上限:Collection,Set>,Object
其中 INT#1 是交集类型:
INT#1 扩展 Object,Set>,Collection

当我尝试用 JDK 1.8.0_121 编译它时,我得到一个不同的错误。但是当我或同事尝试用 JDK 1.8.0_05、1.8.0_20、1.8.0_40 或 1.8.0_45 编译它时,它编译得很好!

TreeSet::new 替换为() -&gt; new TreeSet&lt;&gt;() 可使此编译在所有版本上都没有错误。

我认为这个程序显然是合理的:print 的参数将是一个TreeSet&lt;String&gt;,它符合Set&lt;?&gt;。此外,错误消息对我来说毫无意义:ObjectSet&lt;?&gt;Collection&lt;String&gt; 的交集类型应该符合 Collection&lt;String&gt;Set&lt;?&gt;Object 的上限!

发生了什么事?这是一个错误吗?或者这就是类型推断应该如何工作的?为什么之前有效?我怎样才能让它再次工作(不使用 lambda 而不是方法引用)?

【问题讨论】:

  • 这可能是一个错误。在 java bug 数据库中,有一大堆类型推断(这里有一些关于交叉类型可能适用也可能不适用),其中许多仍然是开放的,一些在 JDK9 中修复,还有一小部分向后移植到 8。对于它的价值,我可以在javac 10.0.2 中复制你的,但不是 Eclipse 的编译器ecj 3.14.0.v20180528

标签: java generics compiler-errors type-inference compiler-bug


【解决方案1】:

这看起来像错误:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8219318 截至 2019 年 7 月 16 日,Oracle 已确认他们可以重现此错误,但尚未修复。

您的测试用例和错误数据库中的测试用例都可以使用 Oracle 1.8.0_191 重现,它们在使用 ecj (Eclipse) 的所有测试版本中都可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    相关资源
    最近更新 更多