关于打开两个 Closeable
实例的方法,Findbugs 让我感到烦恼,但我不明白为什么。
来源
public static void sourceXmlToBeautifiedXml(File input, File output)
throws TransformerException, IOException, JAXBException {
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
try {
fileReader.close();
} finally {
fileWriter.close();
}
}
}
查找错误分析
Findbugs 告诉我
Method [...] may fail to clean up java.io.Reader [...]
并指向带有 FileReader fileReader = ...
问题
谁错了:我还是 Findbugs?
最佳答案
FindBugs 是正确的:如果FileWriter 的构造函数抛出异常,文件读取器将不会关闭。要验证这一点,请尝试为 output
传递一个无效的文件名。
我会这样做:
FileReader fileReader = new FileReader(input);
try {
FileWriter fileWriter = new FileWriter(output);
try {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
} finally {
fileWriter.close();
}
} finally {
fileReader.close();
}
请注意,关闭时抛出的异常的处理可以改进,因为通过抛出异常来离开 finally block 将导致 try 语句通过抛出该异常而终止,吞没 try block 中抛出的任何异常,这通常对调试更有用。有关如何避免这种情况的简单方法,请参阅 duffymo 的回答。
编辑:从 Java 7 开始,我们可以使用 try-with-resources 语句,它允许正确和简洁地处理这些极端情况:
try (
FileReader fileReader = new FileReader(input);
FileWriter fileWriter = new FileWriter(output)
) {
// may throw something
sourceXmlToBeautifiedXml(fileReader, fileWriter);
}
关于Java资源管理: understanding Findbugs results,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2441853/