使用lambda表达式时,Java 8泛型+异常编译时错误

Lal*_*and 8 java generics lambda java-8

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

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

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

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


错误信息

Error:(32, 43) java: unreported exception E; must be caught or declared to be thrown
Run Code Online (Sandbox Code Playgroud)

import java.util.ArrayList;
import java.util.List;


public class JavaBugTest
{
    interface AbleToThrowException<E extends Exception>
    {
    }

    interface Parameter {
        public <E extends Exception> Object execute(AbleToThrowException<E> algo) throws E;
    }

    interface ThrowsRuntimeException extends AbleToThrowException<RuntimeException>
    {
    }

    static ThrowsRuntimeException foo;


    public static Object manualLambda(Parameter p)
    {
        return p.execute(foo);
    }

    public static void main(String[] args)
    {
        List<Parameter> params = new ArrayList<>();
        params.stream().map(p -> p.execute(foo)); // Gives a compile time error.
        params.stream().map(JavaBugTest::manualLambda); // Works fine.
    }

}
Run Code Online (Sandbox Code Playgroud)

系统设置

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

Sot*_*lis 3

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

params.stream().map(p -> p.<RuntimeException>execute(foo)); // Gives a compile time error.
Run Code Online (Sandbox Code Playgroud)

如果没有显式类型参数,JDK 编译器似乎无法从调用上下文中推断出类型参数,尽管它应该这样做。这是一个错误,应该这样报告。我现在已经报告了这个问题,并会在收到新的详细信息后更新这个问题。

错误报告