Java8的Lambda和例外
我想知道是否有人可以向我解释下面这个怪事。 我正在使用Java 8更新11。
给定这种方法
private <F,T> T runFun(Function<Optional<F>, T> fun, Optional<F> opt) { return fun.apply(opt) ; }
如果我首先构造一个函数Object,并将其传入上面的方法,则编译。
private void doesCompile() { Function<Optional<String>, String> fun = o -> o.orElseThrow(() -> new RuntimeException("nah")); runFun(fun, Optional.of("foo")); }
但是,如果我把这个函数作为一个lambda函数进行内联,编译器说
未报告的exceptionX; 必须被逮捕或宣布被抛出
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
另请参阅可运行的testing代码。
这看起来像是JDK-8054569错误,它不影响Eclipse。
我能够通过replace供应商函数并提取orElseThrow
方法来缩小范围:
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"))); }
然后进一步删除供应商和lambda完全:
abstract <T> void f(T t); abstract <T, X extends Throwable> T g(X x) throws X; void bug() { f(g(new RuntimeException("foo"))); }
这实际上比臭虫报告中的一个更清晰的例子。 如果编译为Java 8,则显示相同的错误,但使用-source 1.7
可以正常工作。
我想有关将generics方法返回types传递给generics方法参数的事情导致exception的types推断失败,所以它假定types是Throwable,并且抱怨说这个检查的exceptiontypes没有被处理。 如果你声明bug() throws Throwable
或更改绑定到X extends RuntimeException
(所以它没有选中),错误消失。
这是为我解决了这个问题:
而不是写作
optional.map(this::mappingFunction).orElseThrow(() -> new BadRequestException("bla bla"));
我写了:
optional.map(this::mappingFunction).<BadRequestException>orElseThrow(() -> new BadRequestException("bla bla"));
添加显式的<BadRequestException>
有助于这些lambda边缘情况(这是非常恼人的…)
更新:这是万一你不能更新到最新的JDK版本,如果你可以你应该…
如果您正在尝试编译其他人的项目,请尝试升级到1.8.0_92
- 我怎样才能实现Iterable接口?
- 为什么char 首选string密码?
- 与MySql的连接正在自动中止。 如何正确configurationConnector / J?
- 如何用Swing制作canvas?
- 如何在Java中创build文件夹?
- 在Hibernate Validator 4.1+中,@NotNull,@NotEmpty和@NotBlank有什么区别?
- 一个Java字符串可以有多少个字符?
- hibernate – @ElementCollection – 奇怪的删除/插入行为
- java.lang.NoClassDefFoundError:org / springframework / core / env / ConfigurableEnvironment