Guava:Throwables.propagate和InterruptedException

Ale*_*age 13 java exception-handling interrupted-exception guava

InterruptedException在Guava中使用Throwables.propagate(e)时,处理s 的最佳实践是什么?

我喜欢使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*irk 8

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

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

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

我强烈的观点InterruptedException是,InterruptedException实施工具Exception完全以这种方式被打破:它需要特殊处理,其他例外则不需要.

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

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

然后再考虑一下这个调用者ExecutionException e:

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

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

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

  • 对于编写`throw new RuntimeException(e)`而言,包含异常的异常(特别是当它没有添加任何有用的东西时,例如关于当前上下文的附加消息)是令人讨厌的噪声.无论何处可以避免噪音(例如,它已经是未经检查的例外)那么很棒.有一种观点认为API应该尽可能使用未经检查的例外.即使一个人不买这个论点,人们仍然必须实现以这种方式编写的其他人的接口.所以请不要弃用`Throwables.propagate(e)`! (4认同)