为什么这个分支打破类型推断? [英] Why does this branch break type inference?
问题描述
我在Java中使用了本地实现的
,它有这样的方法:
I'm using a home-grown implementation of Either
in Java, which has a methods like this:
public static <L, R> Either<L, R> left(final L value);
public static <L, R> Either<L, R> right(final R value);
public <T> T fold(
final Function<? super L, ? extends T> leftFunction,
final Function<? super R, ? extends T> rightFunction);
这两种方法编译并正常工作:
These two methods compile and work fine:
Either<Foo, Bar> rightToLeft() {
Either<Foo, Bar> input = Either.right(new Bar());
return input.fold(
l -> null,
r -> Either.left(new Foo())
);
}
Either<Foo, Bar> rightToRight() {
Either<Foo, Bar> input = Either.right(new Bar());
return input.fold(
l -> null,
r -> Either.right(new Bar())
);
}
此方法无法编译:
Either<Foo, Bar> rightToLeftOrRightConditionally() {
Either<Foo, Bar> input = Either.right(new Bar());
return input.fold(
l -> null,
r -> {
if (r.equals("x")) {
return Either.left(new Foo());
}
return Either.right(new Bar());
});
}
错误:
incompatible types: inferred type does not conform to upper bound(s)
inferred: Either<? extends Object,? extends Object>
upper bound(s): Either<Foo,Bar>,java.lang.Object
(我已经修剪了包限定符以使错误更具可读性)
(I've trimmed out the package qualifiers to make the error more readable)
我可以通过指定类型来编译:
I can make it compile by specifying the types:
if (r.equals("x")) {
return Either.<Foo, Bar> left(new Foo());
}
return Either.<Foo, Bar> right(new Bar());
但为什么我需要?我怎样才能避免这种代码混乱?
But why do I need to? And how can I avoid this code clutter?
推荐答案
此代码应该有效。
它编译最新的JDK,1.8.0_121。
It compiles on the latest JDK, 1.8.0_121.
它无法在JDK 1.8.0-51上编译。
It fails to compile on JDK 1.8.0-51.
这意味着它很可能是此版本JDK中的一个错误,因为除非修复错误,否则更高版本不应更改编译器的行为。它可能是错误 JDK-8055963 。
This means it's most likely a bug in this version of the JDK, since later versions should not change the behaviour of the compiler unless to fix a bug. It may be bug JDK-8055963.
因此,解决方案是:
- 升级编译器
- 如果你无法升级编译器(例如,其他人,顽固,拥有构建系统),坚持使用现有的解决方法使类型明确。
这篇关于为什么这个分支打破类型推断?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!