在Java中创建异常安全执行包装器

时间:2018-08-18 16:59:05

标签: java android exception error-handling exception-handling

我有很多使用try / catch的代码,并且几乎在所有情况下我都采取相同的操作。我想做的是通过创建我可以说的内容来简化我的错误处理

ManagedExceptionEnvironment() {
    // The code that might throw exceptions
}

然后在ManagedExceptionEnvironment内部,它具有共享的错误处理逻辑。

对此,我最初的想法是让ManagedExceptionEnvironment的构造函数使用Runnable,但是如果您将可能在匿名Runnable的{​​{1 }}方法,那么它仍然会抱怨没有实现run / try,即使您要传递给它的容器已经照顾好了它。

我想另一种选择是只处理最高级别的错误,并让它们不断抛出新的级别,尽管这似乎很冒险。

编辑:我想这里的一个选项(我不知道这是否是Java中的东西)是某种宏?

编辑2:在使用C预处理器向Java src中注入宏时,刚刚做了一些粗略的阅读,这确实令人恐惧。因此,将宏作为解决方案。

3 个答案:

答案 0 :(得分:3)

除非# initialize your data store要扩展一些现有的类,否则与ManagedExceptionEnvironment方法相反,在这里使用Java类没有任何价值。因此,您可以这样写:

static

然后,在需要的地方可以致电:

public static <T> T boomProtector(Callable<T> thingThatMightGoBoom) {
  try {
    return thingThatMightGoBoom.call();
  }
  catch(Exception e) {
    // TODO: your standard catch logic
  }

  return null;
}

其中Whatever result = boomProtector(() -> earthShatteringKaboom()); Whatever返回的类型。如果earthShatteringKaboom()返回一个对象,则在earthShatteringKaboom()中得到它。如果引发异常,则将执行您的标准捕获逻辑,并且resultresult

(注意:我正在显示示例null调用的Java 8语法,您需要在项目中启用该语法,例如通过Android Studio中的“文件”>“项目设置”>“ app”,或者使用匿名boomProtector()的内部类实现

答案 1 :(得分:1)

如何将其包装在这样的接口中?

class ManagedExceptionEnvironment {
    public static void safeExecution(Wrapper w) {
        try {
            w.codeThatThrows();
        } catch (Exception e) {
            // your error handling
        }
    }


    public static void example() {
        safeExecution(() -> { throw new Exception(); });
        // Or the old-fashioned way:
        safeExecution(new Wrapper() {
            @Override
            public void codeThatThrows() throws Exception {
                throw new Exception();
            }
        });
    }

    interface Wrapper {
        public void codeThatThrows() throws Exception;
    }
}

诀窍在于,类似于Runnable.run()的方法指定可能引发异常,而run()不会抛出异常。

答案 2 :(得分:1)

您可以将异常作为接口/类/方法的(通用)签名的一部分。请参阅我的问题(How to not throw a generically specified exception?)作为示例。

例如,您可以将其命名为“ process()”,而不是调用方法“ newInstance()”。然后围绕它创建一个类型安全的处理程序。客户只需传递lambda表达式即可。

基本上定义您自己的包装器(如其他答案所示:-)