令人惊讶的“推断的类型不符合上限”错误

时间:2018-11-22 12:15:26

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

当我尝试使用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替换为() -> new TreeSet<>()可使该编译在所有版本上均不会出错。

我认为该程序显然是正确的:print的参数将是TreeSet<String>,它符合Set<?>。此外,错误消息对我来说没有意义:ObjectSet<?>Collection<String>的交集类型应符合Collection<String>,{{1 }}和Set<?>

这是怎么回事?这是错误吗?还是这应该如何进行类型推断?为什么以前起作用?我如何才能使其再次工作(不使用lambda而不是方法引用)?

1 个答案:

答案 0 :(得分:1)

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

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