【发布时间】:2014-10-20 19:33:40
【问题描述】:
我想知道是否有人可以向我解释以下奇怪之处。我正在使用 Java 8 更新 11。
给定这个方法
private <F,T> T runFun(Function<Optional<F>, T> fun, Optional<F> opt) {
return fun.apply(opt) ;
}
如果我首先构造一个函数对象,并将其传递给上面的方法,事情就会编译。
private void doesCompile() {
Function<Optional<String>, String> fun = o -> o.orElseThrow(() -> new RuntimeException("nah"));
runFun(fun, Optional.of("foo"));
}
但是,如果我将函数内联为 lambda,编译器会说
未报告的异常 X;必须被抓住或宣布被扔掉
private void doesNotCompile () {
runFun(o -> o.orElseThrow(() -> new RuntimeException("nah")), Optional.of("foo"));
}
更新: 原来错误消息是由 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
另请参阅here 以获取可运行的测试代码。
【问题讨论】:
-
听起来像是另一个类型推断错误。由于 Eclipse 使用自己的,因此请务必包含有关您收到此错误的 编译器 的详细信息。
-
请注意,如果您使用匿名类,也会发生同样的事情,因此这不是 lambda 问题。
-
顺便说一句:Eclipse 编译它就好了,使用
o.<RuntimeException>orElseThrow(()...解决了这个问题,但是,这不是必需的。 (我认为前段时间在另一个stackoverflow问题中报告了类似的问题,但我现在没有找到它......) -
"mvn -e" 会很有帮助。