当我尝试使用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<?>
。此外,错误消息对我来说没有意义:Object
,Set<?>
和Collection<String>
的交集类型应符合Collection<String>
,{{1 }}和Set<?>
!
这是怎么回事?这是错误吗?还是这应该如何进行类型推断?为什么以前起作用?我如何才能使其再次工作(不使用lambda而不是方法引用)?
答案 0 :(得分:1)
这看起来像错误:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8219318 截至2019年7月16日,Oracle已确认他们可以重现此错误,但尚未修复。
您的测试用例和错误数据库中的一个都可以使用Oracle 1.8.0_191复制,在使用ecj(Eclipse)的所有测试版本中都可以正常工作。