是否优先使用嵌套的try / catch块?
在Java中使用Readers和Streams总是让我感到困惑的一点是 close()
方法可能会引发异常。因为将close方法放在finally块中是个好主意,这需要一些尴尬的情况。我通常使用这种结构:
One of the things that always bugs me about using Readers and Streams in Java is that the close()
method can throw an exception. Since it's a good idea to put the close method in a finally block, that necessitates a bit of an awkward situation. I usually use this construction:
FileReader fr = new FileReader("SomeFile.txt");
try {
try {
fr.read();
} finally {
fr.close();
}
} catch(Exception e) {
// Do exception handling
}
但我也看到了这种结构:
But I've also seen this construction:
FileReader fr = new FileReader("SomeFile.txt");
try {
fr.read()
} catch (Exception e) {
// Do exception handling
} finally {
try {
fr.close();
} catch (Exception e) {
// Do exception handling
}
}
我更喜欢第一种结构,因为只有一个捕捉块,它看起来更优雅。是否有理由真正选择第二种或替代结构?
I prefer the first construction because there's only one catch block and it just seems more elegant. Is there a reason to actually prefer the second or an alternate construction?
更新:如果我指出同时读取
和关闭
只抛出IOExceptions?因此,在我看来,如果读取失败,关闭将因同样的原因失败。
UPDATE: Would it make a difference if I pointed out that both read
and close
only throw IOExceptions? So it seems likely to me that, if read fails, close will fail for the same reason.
我会一直这样做第一个例子。
I would always go for the first example.
如果close是抛出一个异常(实际上对于FileReader永远不会发生),那么标准的处理方法就不会抛出适合呼叫者的例外?近似的例外几乎肯定胜过你使用资源的任何问题。如果你的异常处理的想法是调用System.err.println,第二种方法可能更合适。
If close were to throw an exception (in practice that will never happen for a FileReader), wouldn't the standard way of handling that be to throw an exception appropriate to the caller? The close exception almost certainly trumps any problem you had using the resource. The second method is probably more appropriate if your idea of exception handling is to call System.err.println.
存在一个问题,即应该抛出多少异常。应始终重新抛出ThreadDeath,但finally中的任何异常都会阻止它。类似地,Error应该比RuntimeException和RuntimeException更多地抛出异常,而不是检查异常。如果你真的想要,你可以编写代码来遵循这些规则,然后用执行习语来抽象它。
There is an issue of how far exceptions should be thrown. ThreadDeath should always be rethrown, but any exception within finally would stop that. Similarly Error should throw further than RuntimeException and RuntimeException further than checked exceptions. If you really wanted to you could write code to follow these rules, and then abstract it with the "execute around" idiom.