我实现了MyInputStream.read()
方法,并注意到该函数内可能会发生InterruptedException
。经过一些搜索,我发现捕获InterruptedException
并重新抛出InterruptedIOException
是很常见的做法,大概像这样:
try {
...
} catch (InterruptedException e) {
//Thread.currentThread().interrupt(); // <=== ???
throw new InterruptedIOException();
}
但只有约50%的代码示例使用Thread.currentThread().interrupt()
。
尽管吞下InterruptedException
是最糟糕的事情,但在抛出其他异常之前,我应该重新中断当前线程吗?
正:单个中断请求可能有多个“接收者”。
反对:某些功能如日志记录可能在中断状态被清除之前不起作用,这可能会导致微妙的错误。
反对:我们收到关于中断请求的两个通知:线程的中断状态和异常。最初只有一个通知:要么线程的中断状态为true,要么抛出InterruptedException
,但不会同时发生。
正:实际上没有人真正针对可能抛出的I/O异常测试代码,而InterruptedIOException
与其他I/O异常不同;catch(IOException)
子句可能会吞下中断状态。
PS 看起来无论我做什么,InterruptedIOException
是一种非常特殊的要求特殊处理的IOException
问题都不会解决。
PPS (编辑)
我不能让原始的InterruptedException
传播,因为InputStream.read()
不能抛出InterruptedException
(它会throws IOException
而不抛出其他任何内容)。
而我无法预测调用MyInputStream.read()
的上下文:MyInputStream
的一个实例可能被传递给任何接受InputStream
参数的Java或第三方库函数。
至于旧错误,看起来它只是已关闭,而不是解决了;而中断状态的真正目的是使代码行为不同。
InterruptedIOException
的原因是它不能方便地嵌入其他异常作为原因。根据上下文,我可能会只是throw new IOException(e)
,这样当我在上层捕获异常时仍然可以获取到根本原因。 - Ibrahim AriefinitCause(...)
。 三行代码就能完成任务:InterruptedIOException ioExc = new InterruptedIOException(); ioExc.initCause(e); throw ioExc;
- Dan Armstrong