Java8 Lambdas和异常
我不知道是否有人能给我解释一下下面的怪事。我正在使用Java8更新11 给出了这种方法Java8 Lambdas和异常,java,lambda,java-8,Java,Lambda,Java 8,我不知道是否有人能给我解释一下下面的怪事。我正在使用Java8更新11 给出了这种方法 private <F,T> T runFun(Function<Optional<F>, T> fun, Optional<F> opt) { return fun.apply(opt) ; } 更新: 原来错误消息是由maven缩写的。如果直接使用javac编译,则错误为: error: unreported exception X; must be
private <F,T> T runFun(Function<Optional<F>, T> fun, Optional<F> opt) {
return fun.apply(opt) ;
}
更新: 原来错误消息是由maven缩写的。如果直接使用javac编译,则错误为:
error: unreported exception X; must be caught or declared to be thrown
runFun(o -> o.orElseThrow(() -> new RuntimeException("nah")), Optional.of("foo"));
^
where X,T are type-variables:
X extends Throwable declared in method <X>orElseThrow(Supplier<? extends X>)
T extends Object declared in class Optional
错误:未报告的异常X;必须被抓住或宣布被抛出
runFun(o->o.orelsetrow(()->newruntimeexception(“nah”)),可选的.of(“foo”);
^
其中X,T是类型变量:
X扩展了在方法orelsethow(Supplier中声明的Throwable,这看起来像是一个bug案例,它不会影响Eclipse
通过使用供应商替换函数并提取orelsetrow
方法,我可以缩小范围:
abstract <T> void f(Supplier<T> s);
abstract <T, X extends Throwable> T g(Supplier<? extends X> x) throws X;
void bug() {
f(() -> g(() -> new RuntimeException("foo")));
}
摘要无效f(供应商);
摘要T g(供应商这就是我解决问题的原因:
而不是写作
optional.map(this::mappingFunction).orElseThrow(() -> new BadRequestException("bla bla"));
我写道:
optional.map(this::mappingFunction).<BadRequestException>orElseThrow(() -> new BadRequestException("bla bla"));
optional.map(this::mappingFunction).orelsetrow(()->new-BadRequestException(“bla-bla”);
添加显式的
有助于处理这些lambda边缘情况(非常烦人…)
更新:这是为了防止您无法更新到最新的JDK版本,如果可以,您应该…如果您试图编译其他人的项目,请尝试升级到1.8.0_92类似于@keisar,我可以通过指定类型参数来解决我的问题(请参阅)
但是,我发现简单地将我的异常类设置为自己的供应商要方便得多(因为我在许多地方使用了NotFoundException
):
public class NotFoundException extends RuntimeException
implements Supplier<NotFoundException> {
// Rest of the code
@Override
public NotFoundException get() {
return this;
}
}
如果显式添加
看起来很难看,那么作为一种解决方法,您可以
替换为orElseGet()
听起来像是另一个类型推断错误。由于Eclipse使用自己的类,因此请确保包含有关从中获得此错误的编译器的详细信息。请注意,如果使用匿名类,也会发生同样的情况,因此这不是lambda问题。旁白:Eclipse编译得很好,并且使用o.orElseThrow()…
解决了这个问题,但是,这不应该是必要的。(我认为不久前在另一个stackoverflow问题中报告了类似的问题,但我现在没有找到它…“mvn-e”可能会有帮助。从1.8.0_45更新到1.8.0_92,它解决了我的问题。感谢我使用最新版本的Java,但仍然收到一个错误..getorelsetrow(throwable帮了我的忙。谢谢。这帮了我的忙。谢谢,无法升级,因为我没有这台机器。我使用的是1.8.0_144,仍然必须使用你的解决方案。它帮了我的忙。Racle的1.8.0_171也坏了。1.8.0_181也需要显式转换。你确定吗?我在_101中仍然有这个错误,其他人在_171中报告这个错误。我认为你不能抛出一个错误。)n类似这样的内联异常…throw语句需要位于块中。
optional.map(this::mappingFunction).orElseThrow(() -> new BadRequestException("bla bla"));
optional.map(this::mappingFunction).<BadRequestException>orElseThrow(() -> new BadRequestException("bla bla"));
public class NotFoundException extends RuntimeException
implements Supplier<NotFoundException> {
// Rest of the code
@Override
public NotFoundException get() {
return this;
}
}
// Distribution.rep().get(id) returns a java.util.Optional
Distribution distro = Distribution.rep().get(id).orElseThrow(
new NotUniqueException("Exception message"));
.orElseGet(() -> throw new RunTimeException("foo"));