5

我不明白为什么编译器会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
    }

警告消失了。

4

1 回答 1

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对我来说似乎有缺陷(它有效,但我强烈反对使用它):任何资源都应该能够通过调用close. 如果你的资源需要DatabaseConnectionPool.freeConnection被调用来关闭它,你就违反了java的资源契约。如果您使用 try-with-resource 语句,则无论如何您都别无选择:该语句将调用close而不是您的方法。

于 2014-06-27T10:43:39.667 回答