使用Lambda来包装具有相同异常处理的方法

时间:2015-11-19 03:33:29

标签: java lambda

我想要使用相同的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评估为参数,但从概念上讲,这就是我想要添加包装的地方。

1 个答案:

答案 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);