我在其中一个程序上运行了一个动态代码分析工具,这个模式被识别为资源泄漏:
...
FileInputStream fileInputStream = new FileInputStream(file);
try {
data = someMethod(new BufferedInputStream(fileInputStream));
// Assume that someMethod(InputStream) internally reads the stream
// until BufferedInputStream.read() returns -1.
...
}
finally {
...
try {
fileInputStream.close();
} catch (IOException e) {
...
}
}
具体来说,分析工具将new BufferedInputStream(...)
调用标记为资源泄漏,因为它永远不会关闭。但是,在此模式中,基础流fileInputStream
已关闭,BufferedInputStream
超出范围。
注意:当我最初发布问题时,我忽略了清楚,但我意识到这不是“最佳”实现。但是,如果这里没有事实上的资源泄漏,那么我们不太可能为这种模式的所有实例搜索我们的遗留代码库并关闭外部流或用更新的构造替换它们,例如try-with-resources--即,“如果没有损坏,请不要修理它。”
鉴于这种情况,这实际上是资源泄漏吗?
答案 0 :(得分:3)
这不太可能是实际的资源泄漏,但编写这样的代码绝对不是最佳做法。
一般情况下,您应该始终在最外层的流上调用close
,这将流向内部流。
如果您使用的是Java 7,则可以使用新的try-with-resources语法,并避免使用finally块。
答案 1 :(得分:2)
在这种情况下没有资源泄漏。但是,关闭BufferedInputStream
代替(或同样)的成本是最小的,因此最简单的是添加(严格)不必要的近距离以使分析工具满意。
典型的静态分析工具正在代码中查找指示错误的结构模式。在这种情况下,模式匹配方法会给资源泄漏带来误报。
答案 2 :(得分:0)
因为Java没有解构器,所以超出范围的对象不一定会关闭流。 Java确实有终结器,但不能保证它们会被调用。 BufferedInputStream不一定会被关闭。但是,由于底层流已关闭,我认为这并不重要。
最好确保关闭流,但可能并不重要。