提供lambda参数时,为什么必须捕获异常?

问题描述

请考虑以下示例:

@PUT
@Path("/test")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "swagger description",notes = "swagger notes",response = TestResponse.class)
public Response saveOrUpdateTest(@QueryParam("a") String a,Test test) {
    DataServiceFactory dataServiceFactory = getDataServiceFactory();
    return dataServiceFactory.getTestDataService().saveOrUpdateTest(test);
}

这里是一个问题:上例中的lambda参数是一个对象,稍后将在“ display()”方法内执行该对象。将参数传递给“ display()”时显然不会执行。

为什么编译器拒绝它?我认为用try ... catch包围它是非常合理的,仅在实际调用lambda时才捕获。

解决方法

这是因为Supplier功能接口的签名:

T get();

如您所见,方法get并未声明抛出Exception(没有其他 checked 异常)。

在Java中,存在已检查未检查异常(未检查的异常是从RuntimeException继承的异常)。必须通过在catch块中捕获已检查的异常,或者通过声明方法throws来处理该异常。

如果Supplier.get的签名是:

T get() throws Exception:

代码可以正常编译。

尝试抛出RuntimeException而不是Exception,代码可以正常编译。


编辑:根据彼得·劳瑞(Peter Lawrey)在评论中的建议,如果您确实需要在lambda表达式中抛出一个已检查的异常,则可以使用例如Callable,其唯一的一种方法签名如下:

T call() throws Exception;

您只需要将Callable传递给display方法,而不是Supplier

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...