Java javac 1.8.0_45 和 javac 1.8.0_92 之间的类型推断差异?
Java type inference differences between javac 1.8.0_45 and javac 1.8.0_92?
我有一些使用 javac 1.8.0_92
编译的代码:
public final class Either<L, R> {
// ...
private final L l;
private final R r;
// ...
public <T> T join(final Function<L, T> f, final Function<R, T> g) {
Preconditions.checkNotNull(f);
Preconditions.checkNotNull(g);
return which == LeftOrRight.LEFT ?
f.apply(l) :
g.apply(r);
}
public Optional<L> left() {
return join(Optional::of, x -> Optional.empty());
}
// ...
}
但是,对于 javac 1.8.0_45
,需要一些额外的类型 (L
):
public Optional<L> left() {
return join(Optional::<L>of, x -> Optional.<L>empty());
}
如您所想,这会导致用户从源代码构建的包出现问题。
这是为什么?
这是 Java 特定版本的错误吗?
是的,这是 JDK 错误,其中类型推断因嵌套调用而失败。如果将任一参数设置为 null
,代码将编译。
https://bugs.openjdk.java.net/browse/JDK-8055963
已为 Java 9 提交修复,但他们也将其反向移植到 8u60:
我有一些使用 javac 1.8.0_92
编译的代码:
public final class Either<L, R> {
// ...
private final L l;
private final R r;
// ...
public <T> T join(final Function<L, T> f, final Function<R, T> g) {
Preconditions.checkNotNull(f);
Preconditions.checkNotNull(g);
return which == LeftOrRight.LEFT ?
f.apply(l) :
g.apply(r);
}
public Optional<L> left() {
return join(Optional::of, x -> Optional.empty());
}
// ...
}
但是,对于 javac 1.8.0_45
,需要一些额外的类型 (L
):
public Optional<L> left() {
return join(Optional::<L>of, x -> Optional.<L>empty());
}
如您所想,这会导致用户从源代码构建的包出现问题。
这是为什么?
这是 Java 特定版本的错误吗?
是的,这是 JDK 错误,其中类型推断因嵌套调用而失败。如果将任一参数设置为 null
,代码将编译。
https://bugs.openjdk.java.net/browse/JDK-8055963
已为 Java 9 提交修复,但他们也将其反向移植到 8u60: