Zho*_*hou 2 java lambda functional-interface
考虑以下示例:
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";
});
}
}
Run Code Online (Sandbox Code Playgroud)
问题来了:上面例子中的 lambda 参数是一个稍后将在“display()”方法中执行的对象。将参数传递给“display()”时显然不会执行它。
为什么会被编译器拒绝?我认为用 try...catch 包围它是很合理的,只有当 lambda 被实际调用时。
这是因为Supplier功能接口的签名:
T get();
Run Code Online (Sandbox Code Playgroud)
如您所见,该方法get未声明为抛出Exception(也没有任何其他已检查的 异常)。
在 Java 中,存在已检查和未检查异常(未检查异常是从 继承的异常RuntimeException)。必须通过在catch块中捕获它们或通过声明throws该异常的方法来处理受检查的异常。
如果签名Supplier.get是:
T get() throws Exception:
Run Code Online (Sandbox Code Playgroud)
代码会编译得很好。
尝试 throwRuntimeException而不是,Exception代码将编译得很好。
编辑:根据 Peter Lawrey 在评论中的建议,如果您确实需要从 lambda 表达式中抛出已检查的异常,则可以使用 eg Callable,其唯一一个方法的签名如下:
T call() throws Exception;
Run Code Online (Sandbox Code Playgroud)
您只需要将 a 传递Callable给您的display方法而不是 a Supplier。
| 归档时间: |
|
| 查看次数: |
65 次 |
| 最近记录: |