【发布时间】:2019-04-02 20:56:33
【问题描述】:
在测试时,我将我的 Junit 升级到了 5.0(因此用新版本替换了我的一些 assertTrue() 方法)。这样做之后,我发现我的一个测试没有编译。我将问题简化为没有junit或其他依赖项的普通旧java。结果是下面的代码无法编译:
public static void recreate() {
// This does NOT work
Recreation.assertTrue(identity((x) -> Boolean.TRUE));
// This DOES work
Recreation.assertTrue(identity((String x) -> Boolean.TRUE));
}
private static class Recreation {
public static void assertTrue(boolean b) {
System.out.println("boolean argument: " + b);
}
// If this method is removed, the code will compile.
public static void assertTrue(Supplier<Boolean> booleanSupplier) {
System.out.println("supplier argument: " + booleanSupplier.toString());
}
}
private static <K> K identity(Function<String, K> function) {
return function.apply("hello");
}
如上例所示,如果满足以下任一条件,则代码将编译:
指定了lambda参数类型
重载的assertTrue(Supplier booleanSupplier)方法被移除
这是类型推断/擦除的问题,还是这里可能发生了什么?
构建错误:
Error:(10, 35) incompatible types: inference variable K has incompatible bounds
lower bounds: java.util.function.Supplier<java.lang.Boolean>,java.lang.Object
lower bounds: java.lang.Boolean
规格:
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment (build 11.0.1+13-Ubuntu-3ubuntu114.04ppa1)
OpenJDK 64-Bit Server VM (build 11.0.1+13-Ubuntu-3ubuntu114.04ppa1, mixed mode, sharing)
OS: Ubuntu 14.04.5 LTS
编辑:确认 Java 8 上也存在该问题:
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
exit status 1
Main.java:10: error: incompatible types: inferred type does not conform to upper bound(s)
Recreation.assertTrue(identity((x) -> Boolean.TRUE));
^
inferred: Boolean
upper bound(s): Supplier<Boolean>,Object
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
【问题讨论】:
-
你用什么版本的Java编译?
-
在 Eclipse 4.10.0 中为我编译。
-
@JacobG。使用 Java 11 运行,我刚刚更新了描述。谢谢!
标签: java generics type-inference