【发布时间】: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 替换为() -> new TreeSet<>() 可使此编译在所有版本上都没有错误。
我认为这个程序显然是合理的:print 的参数将是一个TreeSet<String>,它符合Set<?>。此外,错误消息对我来说毫无意义:Object、Set<?> 和 Collection<String> 的交集类型应该符合 Collection<String>、Set<?> 和 Object 的上限!
发生了什么事?这是一个错误吗?或者这就是类型推断应该如何工作的?为什么之前有效?我怎样才能让它再次工作(不使用 lambda 而不是方法引用)?
【问题讨论】:
-
这可能是一个错误。在 java bug 数据库中,有一大堆类型推断(这里有一些关于交叉类型可能适用也可能不适用),其中许多仍然是开放的,一些在 JDK9 中修复,还有一小部分向后移植到 8。对于它的价值,我可以在
javac 10.0.2中复制你的,但不是 Eclipse 的编译器ecj 3.14.0.v20180528
标签: java generics compiler-errors type-inference compiler-bug