使用lambda表达式时出现Java 8泛型+异常编译时错误
几天前,我开始重构一些代码以使用新的Java8Streams库。不幸的是,我在使用一个方法执行Stream::map时遇到了编译时错误,该方法被声明为抛出一个泛型E,该泛型E被进一步指定为RuntimeException
有趣的是,当我切换到使用方法引用时,编译时错误消失了
这是一个bug,还是我的方法引用与lambda表达式不等价
(另外,我知道我可以用参数::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<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.
}
}
系统设置
- 操作系统:Windows x64
- Java编译器版本:Oracle JDK 1.8.0_11
- IDE:Intellij
# 1 楼答案
一个非常简单的解决方案是显式地为
Parameter#execute(..)
提供一个类型参数如果没有显式类型参数,JDK编译器似乎无法从调用上下文推断类型参数,尽管它应该这样做。这是一个bug,应该这样报告。我现在已经报告了,当我有新的细节时,我会用新的细节更新这个问题
Bug Report