我想要使用相同的try / catch处理来包装许多方法。我认为lambdas可以帮助我,但我很难搞清楚语法。
以下是我想要实现的目标。
method1(..., result -> method2(result, ...));
method2是method1结果的处理程序。我想用一个常见的try / catch语句包装method2,这对于大量的处理程序是通用的,而不必将语句复制/粘贴到所有处理程序。
注意:这些是未经检查的例外。
*编辑 - 我尝试做的具体例子。
我使用Vert.x,他们使用Handler的常见设计模式。这是他们的SQL接口的一个例子
query(String sql, Handler<AsyncResult<ResultSet>> resultHandler)
Handler是一个简单的1函数接口:
void handle(E event)
所以基本上,在&#34; sql&#34;中定义的查询执行,结果发送到resultHandler。以下是使用中的一个示例:
connection.query("SELECT * from table1", asyncResult -> {
// do something with results
}
以上使用了他们的文档标准编码风格。我个人更喜欢在命名函数中处理各种原因的结果,所以它改为:
connection.query("SELECT * from table1", asyncResult -> method1(asyncResult));
void method1(AsyncResult<ResultSet> asyncResult) {
// do something with results
}
我无法控制query()界面,所以我坚持使用这种模式。我不确定Tagir的解决方案是否会在这种情况下发挥作用,但我会在早上玩弄它。
* edit2 - 我应该注意到我试图在上面的例子中将method1包装在异常包装器中,所以理想情况下,我在query()调用中添加包装器调用。所以我正在寻找的是:
connection.query("SELECT * from table1", wrap(asyncResult -> method1(asyncResult)));
显然,我无法以这种方式使用它,因为它会将原始lambda评估为参数,但从概念上讲,这就是我想要添加包装的地方。
答案 0 :(得分:3)
您可以使用Runnable
功能接口来实现处理异常的方法:
public static void handleExceptions(Runnable r) {
try {
r.run();
}
catch(RuntimeException ex) {
ex.printStackTrace();
}
}
并称之为:
handleExceptions(() -> method2(foo, bar));
如果您的method2
产生了结果,您应该确定在发生异常的情况下默认结果是什么(并且您不会在处理程序中重新抛出它)。对于这种情况,您可以使用Supplier
功能界面:
public static <T> T handleExceptions(Supplier<T> r, T defaultValue) {
try {
return r.get();
}
catch(RuntimeException ex) {
ex.printStackTrace();
return defaultValue;
}
}
并且这样打电话:
// set result to null if exception occurred
result = handleExceptions(() -> method2(foo, bar), null);
或者
// do not modify the result if exception occurred
result = handleExceptions(() -> method2(foo, bar), result);