java为什么在提供lambda参数时必须捕获异常?
考虑下面的例子:
public class LambdaArgsTest {
private static void display(Supplier<?> arg) {
try {
// this is the place where the Exception("wrong") might be thrown
// and it is in fact handled
System.out.println(arg.get());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
display(() -> {
if(/*some condition*/) {
// this statement will be rejected due to unhandled exception
throw new Exception("wrong");
}
return "abcde";
});
}
}
问题来了:上面示例中的lambda参数是一个对象,稍后将在“display()”方法中执行。将参数传递给“display()”时,它显然不会执行
为什么编译器会拒绝它?我认为用try来包围它是很合理的。。。只在实际调用lambda时捕获
# 1 楼答案
这是因为
Supplier
功能接口的签名:如您所见,方法
get
没有声明为抛出Exception
(也没有任何其他选中的异常)在Java中,有选中的和未选中的异常(未选中的异常是从
RuntimeException
继承的异常)。必须通过在catch
块中捕获已检查的异常,或通过声明方法throws
处理该异常来处理已检查的异常如果
Supplier.get
的签名是:代码可以很好地编译
尝试抛出
RuntimeException
而不是Exception
,代码将可以很好地编译编辑:根据Peter Lawrey在评论中的建议,如果确实需要从lambda表达式中抛出选中的异常,可以使用例如^{} ,其唯一一个方法的签名如下:
只需要将
Callable
传递给display
方法,而不是Supplier