番石榴:Throwables.propagate and InterruptedException

在番石榴中使用Throwtables.propagate(e)时处理s的最佳实践是什么?InterruptedException

我喜欢使用 ,特别是在不引发任何已检查异常的方法中,并且异常处理是调用方的责任。但它并没有像我对DisruptedException所期望的那样。throw Throwables.propagate(e)

我不想失去线程被中断的事实,所以我最终写了这样的东西:

public void run() {
    Callable c = ...;
    try {
        c.call();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw Throwables.propagate(e);
    } catch (Exception e) {
        throw Throwables.propagate(e);
    }
}

有没有办法在番石榴做到这一点?有没有一种(向后兼容?!)方法来使用像Throwtables.propagate()这样的东西,如果线程正在包装和传播中断的异常,它将线程设置为中断?


答案 1

方便的是,我们不久前在内部讨论了这个问题。我只复制并粘贴:

我的强硬观点是,它基本上是,人们通常不应该这样做,就像他们通常不应该写一样。(如果他们要写它,他们不妨直接写出来,这样就清楚发生了什么。Throwables.propagate(e)throw new RuntimeException(e)throw new RuntimeException(e)

我的强硬观点 - 通常是人们如何让自己陷入这种混乱 - 是他们通常也不应该这样做。(显然,在某些情况下,显然是正确的做法(基本上是任何顶级的,操作范围的捕获块),但这些都是......显而易见。catch (Exception e)catch (Exception e)

我的强硬观点是,实现完全以这种方式被打破:它需要特殊处理,而其他异常则不需要。InterruptedExceptionInterruptedExceptionException

我对转换为a的强硬意见是“不要”。(就像我上面说的许多其他东西一样,这是有争议的。InterruptedExceptionRuntimeException

因此,一方面,我不确定我们能做些什么来挽救 。另一方面,也许让方法不那么糟糕是件好事。propagate()

然后,再次考虑这个调用方,它捕获:ExecutionException e

throw Throwables.propagate(e.getCause());

中断使用者线程是错误的,就像直接抛出是错误的一样,因为中断是针对计算线程的,而不是使用者线程。e.getCause()

我倾向于独自离开。(正如你可能猜到的那样,我个人倾向于弃用它,但这是一个更大的讨论。propagate()


答案 2

推荐