java - 在 Java 中,您可以将相同的异常处理逻辑合并到一处吗?

标签 java exception code-cleanup functional-interface

我正在尝试清理一些 Java 代码。有许多静态工厂方法都执行相同的异常处理。例如,考虑 createA :

public static A createA() throws XXXX, YYYY {
    try {
        return somethingThatThrows();
    } catch (InterruptedException | ExecutionException e) {
        Throwable throwable = e.getCause();
        if (throwable instanceOf XXXX) {
            throw (XXXX) throwable;
        } else if (e instance of YYYY) {
            throw (YYYY) throwable;
        } else if (throwable != null) {
            throw new RuntimeException(throwable);
        } else {
            throw new RuntimeException(e);
        }
    }
}         

其中有很多create方法(每个方法返回不同的类型)。对于每个方法,都存在此异常处理的副本(即它是重复的)。我希望有一种方法可以避免所有这些相同的代码,并且只在一个地方有这个逻辑。

当然,如果没有异常处理,您只需将逻辑提取到辅助函数中即可解决重复问题 - 事实上,它具有异常处理功能,使其有所不同。以下代码无法构建:

public static void helper(final Exception e) {
    Throwable throwable = e.getCause();
        if (throwable instanceOf XXXX) {
            throw (XXXX) throwable;
        } else if (e instance of YYYY) {
            throw (YYYY) throwable;
        } else if (throwable != null) {
            throw new RuntimeException(throwable);
        } else {
            throw new RuntimeException(e);
        }
}  

public static A createA() throws XXXX, YYYY {
    try {
        return somethingThatThrows();
    } catch (InterruptedException | ExecutionException e) {
        handle(e);
    }
}         

有人有什么建议吗?

最佳答案

这可以通过以下功能方式处理:

@FunctionalInterface
interface SomethingThatThrows<T> {
    T execute() throws XXXX, YYYY, InterruptedException,ExecutionException;
}

private static <T> T handledFuntion(SomethingThatThrows<T> function) throws XXXX, YYYY {
    try {
        return function.execute();
    } catch (InterruptedException | ExecutionException e) {
        Throwable throwable = e.getCause();
        if (throwable instanceof XXXX) {
            throw (XXXX) throwable;
        } else if (e instanceof YYYY) {
            throw (YYYY) throwable;
        } else if (throwable != null) {
            throw new RuntimeException(throwable);
        } else {
            throw new RuntimeException(e);
        }
    }
}

// Use lambda literal - may be better when arguments are involved
public A createA(String arg1) throws XXXX, YYYY {
   return handledFuntion(() -> {
         // write code just like you'd write it in try{} body - 
         // all arguments to createA() are available
         return new A(arg1);
     });
}

// use a method handle, works best when there are no arguments
public B createB() throws XXXX, YYYY {
       return handledFuntion(this::somethingThatMakesB);
}


private B somethingOtherThatMakesB() throws XXXX, YYYY, InterruptedException,ExecutionException {
    // Some logic that creates and returns B
}

编辑:合并@Arkadiy的答案。

关于java - 在 Java 中,您可以将相同的异常处理逻辑合并到一处吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48512425/

相关文章:

java - 开发一个工具来知道谁连接到远程机器?

java - Maven错误: unmappable character for encoding Cp1251

java - 使用 GWT 的网络 worker

java - java中多个for内部的计时方法

java - 我可以在单个类文件中在 java 中定义多个自定义异常并通过方法调用它们吗?

java - 如何使用eclipse检测java类中的空主体方法?

java - 链接列表程序不会删除对象,并且会因未知原因抛出强制转换异常?

java - 如何将 Throw 与多个 if/else 条件一起使用?

ruby-on-rails - rails : How to render a layout around a collection?

javascript - 查找 JS 中使用的 CSS 类