使用lambda表达式时,Java 8generics+exception编译时错误

几天前,我开始重构一些代码以使用新的Java 8 Streams库。 不幸的是,我在使用一个方法执行Stream :: map时遇到了编译时错误,该方法被声明为抛出一个进一步指定为RuntimeException的genericsE.

有趣的是,当我切换到使用方法引用时,编译时错误消失了。

这是一个错误,还是我的方法引用不等同于我的lambda表达式?

(另外,我知道我可以用Parameter :: execute替换p-> p.execute(foo)。我的实际代码有execute方法的附加参数)。


错误信息

Error:(32, 43) java: unreported exception E; must be caught or declared to be thrown 

 import java.util.ArrayList; import java.util.List; public class JavaBugTest { interface AbleToThrowException { } interface Parameter { public  Object execute(AbleToThrowException algo) throws E; } interface ThrowsRuntimeException extends AbleToThrowException { } static ThrowsRuntimeException foo; public static Object manualLambda(Parameter p) { return p.execute(foo); } public static void main(String[] args) { List params = new ArrayList(); params.stream().map(p -> p.execute(foo)); // Gives a compile time error. params.stream().map(JavaBugTest::manualLambda); // Works fine. } } 

系统设置

  • 操作系统:Windows x64
  • Java编译器版本:Oracle JDK 1.8.0_11
  • IDE:Intellij

一个非常简单的解决方案是为Parameter#execute(..)显式提供一个类型参数。

 params.stream().map(p -> p.execute(foo)); // Gives a compile time error. 

如果没有显式类型参数,JDK编译器似乎无法从调用上下文中推断出类型参数,尽管它应该如此。 这是一个bug,应该这样报告。 我现在已经报告了它,并且在我拥有它们时会用新的细节更新这个问题。

错误报告