2014-08-27 77 views
41

我不知道是否有人能够向我解释下面的古怪。我使用Java 8日更新11Java8兰巴达斯和例外

鉴于这种方法

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")); 

} 

但是,如果我内联函数的拉姆达,编译器说

没有报告异常X;必须捕获或声明抛出

private void doesNotCompile() { 
    runFun(o -> o.orElseThrow(() -> new RuntimeException("nah")), Optional.of("foo")); 
} 

更新: 原来的错误信息被行家缩写。如果直接用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可运行测试代码。

+6

听起来像另一种类型的推理错误。请确保在Eclipse使用自己的编译器时包含详细信息*,您会收到此错误。 – 2014-08-27 09:27:28

+0

注意到如果您使用匿名类也会发生同样的事情,所以它不是lambda问题。 – user2504380 2014-08-27 10:38:09

+4

另一方面:Eclipse编译这个就好了,使用'o。 orElseThrow(()...'解决了这个问题,但是,这不应该是必须的(我认为在另一个stackoverflow问题中报告了类似的问题前段时间,但我现在没有找到它......) – Marco13 2014-08-27 11:42:17

回答

29

这看起来像是一个缺陷JDK-8054569,它不影响Eclipse。

我能够通过与供应商更换功能和提取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下正常工作。

我想将一个泛型方法返回类型传递给泛型方法参数会导致异常的类型推断失败,因此它假定类型为Throwable,并且抱怨未检测到此已检查的异常类型。如果声明bug() throws Throwable或将边界更改为X extends RuntimeException(因此未选中),该错误将消失。

+6

从1.8.0_45更新到1.8.0_92,它解决了我的问题。谢谢 – arnm 2016-05-16 20:08:17

34

这就是解决了我的问题:写我写

,而不是

optional.map(this::mappingFunction).orElseThrow(() -> new BadRequestException("bla bla")); 

optional.map(this::mappingFunction).<BadRequestException>orElseThrow(() -> new BadRequestException("bla bla")); 

添加明确<BadRequestException>有助于这些拉姆达边缘的情况下(这是挺烦人的...)

更新:这是如此你不能更新到最新的JDK版本,如果你可以,你应该...

+0

我在最新版本的Java仍然得到一个错误。 getOrElseThrow(throwable帮了我,谢谢。 – 2017-09-28 11:14:51

+0

这帮忙谢谢,不能升级,因为我没有自己的机器 – Alex 2017-10-17 14:01:16

+0

我在1.8.0_144,还是不得不使用你的解决方案,它有帮助 – olyv 2017-10-18 15:32:06

0

如果你想编译别人的项目尝试升级到1.8。0_92