我无法理解为什么编译器会在以下代码中警告我资源泄漏(Resource leak: 'conn' is not closed at this location
):
Connection conn = null;
try {
conn = DatabaseConnectionPool.getConnectionFromPool();
// Some code
try {
// Other code
} catch (final SomeException e) {
// More code
throw e; // Resource leak: 'conn' is not closed at this location
}
} catch (final SQLException | OtherExceptions e) {
// Some more code
} finally {
try {
// Another bunch of code
} finally {
DatabaseConnectionPool.freeConnection(conn);
}
}
请注意,如果我这样写
Connection conn = null;
try {
conn = DatabaseConnectionPool.getConnectionFromPool();
// Some code
try {
// Other code
} catch (final SomeException e) {
// More code
throw e;
} finally {
DatabaseConnectionPool.freeConnection(conn);
}
} catch (final SQLException | OtherExceptions e) {
// Some more code
} finally {
// Another bunch of code
}
警告消失了。
答案 0 :(得分:3)
编译器非常容易转储。它可能无法知道DatabaseConnectionPool.freeConnection(conn)
会在close
上调用conn
。我不确定为什么第二个例子没有触发这个警告,但可能这个功能并不完全完善,可能会产生漏报。基本上,任何资源都应该通过直接在获取资源的地方调用close
方法来关闭;这是编译器可以确定要关闭它的唯一方法,它不是程序间分析来检查被调用函数是否调用close
。
使用java7,您应该考虑使用try-with-resource语句;它是 鼓励处理任何资源的方式,即:
try(Connection conn = ...){
// Do something with conn
// No close necessary here, done implicitly by the try statement
}
通过调用close
以外的方法来关闭连接的整个模式对我来说似乎有缺陷(它有效,但我强烈反对它的用法):任何资源都应该能够通过调用{{}来关闭它自己1}}。如果您的资源需要调用close
来关闭它,那么您违反了Java的资源合同。如果您使用try-with-resource语句,则无论如何都无法选择:语句将调用DatabaseConnectionPool.freeConnection
而不是您的方法。