压制异常作为收集多个异常的方法

4

我有一个重复的模式,即同时运行多个任务,要么它们全部成功,要么整个过程因其中一个任务失败而失败。虽然我可以在第一个任务异常后确定进程失败,但我必须等待所有任务结束才能报告异常。

{
    List<Future<?>> futures = launchTasks();
    boolean anyProcessFailed = false;

    for (Future<?> future: futures)
        try {
            future.get();
        } catch(ExecutionException ex) {
            //This process failed
            anyProcessFailed=true;
        }

    if (anyProcessFailed) throw new Exception();
}

上述代码可以运行,但是在最后抛出的异常没有提及引起它的异常(可以是一个或多个异常)。
问题是:使用Throwable.addSuppressed来实现“异常的多个原因”概念是否是一种良好的做法?还是应该实现自己的Exception类型,公开一个Throwable[] getCauses()方法?
我已经阅读过抑制异常的文档,虽然它们有一个公共API,但只能由JRE在try-with-resources语句期间设置。事实上,try-with-resources是一个普通的旧式try-finally块的语法糖。
示例1:以下代码不会等待其他任务完成,因此其他线程将被留在wild中。
{
    List<Future<?>> futures = launchTasks();

    for (Future<?> future: futures)
        try {
            future.get();
        } catch(ExecutionException ex) {
            //This process failed
            throw new Exception(ex);
        }

}

例子2:我目前在做什么

{
    List<Future<?>> futures = launchTasks();
    Exception ex = new Exception();

    for (Future<?> future: futures)
        try {
            future.get();
        } catch(ExecutionException e) {
            //This process failed
            ex.addSuppressed(e);
        }

    if (ex.getSuppressed().length > 0) throw ex;
}
2个回答

2

通常情况下,如果您的代码中存在真正的异常情况,并且可以为API调用者提供有意义的数据,实现自己的异常是一个很好的做法。否则,使用JDK中的通用异常会是更好的选择。我认为在addSuppressed方法的JavaDoc中,try-finally场景被提及作为该方法在JDK中的示例用法。当然,如果这对您的情况有意义,您也可以使用它。


2
我有一个类似的问题。Java文档现在指出:“请注意,程序员编写的代码也可以利用调用此方法的情况,在存在多个兄弟异常且只能传播一个异常的情况下。” - slycrel

-1
问题是:使用Throwable.addSuppressed实现异常的多个原因的概念是一个好的实践,还是应该实现自己的异常类型,暴露一个Throwable[] getCauses()?
1. 不是。这些不是在JLS和Throwable API中使用术语“抑制”的异常。 2. 是的,尽管我不会称其为causes属性。

一个通用的 Exception 实例只是一个示例。我已经有了我的特定异常。 - usr-local-ΕΨΗΕΛΩΝ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接