Guava:Throwables.propagate和InterruptedException

时间:2012-10-10 12:09:08

标签: java exception-handling guava interrupted-exception

在Guava中使用Throwables.propagate(e)时处理InterruptedException的最佳做法是什么?

我喜欢使用throw Throwables.propagate(e),特别是在不抛出任何检查异常的方法中,以及异常处理是调用者的责任。但它没有做我期望的InterruptedException。

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

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);
    }
}

有没有办法在番石榴做到这一点?有一种(向后兼容的?!)方式使用类似Throwables.propagate()的方法将线程设置为中断,如果它正在包装并传播InterruptedException吗?

1 个答案:

答案 0 :(得分:8)

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

我对Throwables.propagate(e)的强烈意见是,它基本上是throw new RuntimeException(e),人们通常不应该这样做,就像他们通常不应该写throw new RuntimeException(e)一样。 (如果他们要写它,他们也可以直接写它,以便清楚发生了什么。)

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

我对InterruptedException的强烈意见是InterruptedException实现Exception的方式完全是以这种方式实现的:它需要特殊处理,其他例外则不需要。

我对将InterruptedException转换为RuntimeException的强烈意见是“不要”。 (就像我上面提到的其他许多内容一样,这是有争议的。)

所以一方面,我不确定我们能做些什么来挽救propagate()。另一方面,也许让这个方法变坏一点也不错。

然后再考虑这个调用者,它捕获ExecutionException e

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

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

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