有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有一个循环模式,我并行运行多个任务,要么它们都成功了,要么整个过程因为其中一个而失败。虽然我可以确定进程在第一个任务异常之后失败,但我必须等待它们全部结束,然后才能报告异常

{
    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:下面的代码不会等待其他任务完成,因此其他线程将处于空闲状态

{
    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) 个答案

  1. # 1 楼答案

    一般来说,在代码中实现自己的异常始终是一个好的做法,表示真正异常的场景,如果它可以为API的调用方提供有意义的数据。否则,在JDK中使用一个通用异常将是更好的选择。我认为在addSuppressed方法的JavaDoc中,try-finally场景作为该方法在JDK中的示例用法被提到。当然,如果它有意义的话,您可以在您的场景中使用它

  2. # 2 楼答案

    Question is: is it a good practice to use Throwable.addSuppressed to implement the concept of multiple causes of an exception or should I implement my own Exception type that exposes a Throwable[] getCauses()?

    1. 不可以。在JLS和ThrowableAPI中使用术语的意义上,这些不是“抑制”异常
    2. 是的,尽管我不会调用属性causes