在Java中使用Readers和Streams总是让我感到困惑的一件事是该close()方法可以抛出异常.因为将close方法放在finally块中是个好主意,这需要一些尴尬的情况.我通常使用这种结构:
FileReader fr = new FileReader("SomeFile.txt");
try {
try {
fr.read();
} finally {
fr.close();
}
} catch(Exception e) {
// Do exception handling
}
Run Code Online (Sandbox Code Playgroud)
但我也看到了这种结构:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢第一个结构,因为只有一个挡块,它看起来更优雅.是否有理由更喜欢第二种或替代结构?
更新:如果我指出两者read并且close只抛出IOExceptions ,它会有所作为吗?因此,在我看来,如果读取失败,关闭将因同样的原因而失败.
oxb*_*kes 26
我担心第一个例子存在一个大问题,即如果在读取之后或之后发生异常,则finally执行该块.到现在为止还挺好.但是,如果fr.close()然后导致另一个异常被抛出怎么办?这将"胜过"第一个异常(有点像放入return一个finally块),你将失去关于实际导致问题开始的所有信息.
你的finally块应该使用:
IOUtil.closeSilently(fr);
Run Code Online (Sandbox Code Playgroud)
这个实用程序方法的作用如下:
public static void closeSilently(Closeable c) {
try { c.close(); } catch (Exception e) {}
}
Run Code Online (Sandbox Code Playgroud)
我总是会去寻找第一个例子.
如果close是抛出一个异常(在实践中,FileReader永远不会发生),那么标准的处理方式是不是抛出一个适合调用者的异常?近似的例外几乎肯定胜过你使用资源的任何问题.如果你的异常处理的想法是调用System.err.println,第二种方法可能更合适.
存在一个问题,即应该抛出多少异常.应始终重新抛出ThreadDeath,但finally中的任何异常都会阻止它.类似地,Error应该比RuntimeException和RuntimeException更多地抛出异常,而不是检查异常.如果你真的想要,你可以编写代码来遵循这些规则,然后用"执行周期"成语来抽象它.
| 归档时间: |
|
| 查看次数: |
34971 次 |
| 最近记录: |