18

で、よくわからないEclipseという警告を受けました。Resource leak: 'ps' is not closed at this location

私のJavaコードでは、「ps」を準備済みステートメントとして宣言し、それを何度も使用 (およびクローズ) します。次に、次のシーケンスがあります。

try {
    if(condition) {
        ps = c.prepareStatement("UPDATE 1 ...");
    } else {
        ps = c.prepareStatement("UPDATE 2 ...");
    }
    ps.executeUpdate();
} catch (SQLException e) {
    // exception handling
} finally {
    if (null != ps) 
        try { 
            ps.close(); 
        } catch (SQLException e) { 
            // exception handling
        };
}

「リソース リーク」警告は、else セクションの「更新」ステートメントで発生します。ps = nulltry ブロックを開始する前に設定すると、警告は表示されません。

2 番目の UPDATE-Statement がコメント化されている場合、警告は表示されません。

それは理解ですか、それともJava / Eclipseの問題ですか?

4

3 に答える 3

11

この警告が表示された場合は、Java 7 を使用しています。この場合、自分自身を実装するリソースを閉じないでAutoClosableください。tryステートメントの特別な初期化セクションでこれらのリソースを初期化する必要があります。

// decide which update statement you need:
// (your if should be here)
String update = ....;
try (
     ps = c.prepareStatement(update);
) {
   // use prepared statement here.
} catch (SQLException) {
   // log your exception
   throw new RuntimeException(e);
}
// no finally block is needed. The resource will be closed automatically.

if/elseステートメントの存在によって警告が表示または非表示になる理由が実際にはわかりません。しかし、Java 7 では、上記で説明した自動クローズ可能なリソースを使用する方法を推奨しているので、これを試してください。

于 2013-02-13T21:08:00.573 に答える
3

使用しているチェッカーに問題があると思います。

コードをinitializationanduseブロックに分割します。また、初期化ブロックから例外をスローします (または早期復帰を行います)。useこのように、ブロック後にリソースを解放するときに null をチェックする必要はありません

// initialization
// Note that ps is declared final.
// I think it will help to silence your checker
final PreparedStatement ps;

try {
    if( bedingungen ... ) {
        ps = c.prepareStatement("UPDATE 1 ...");
    } else {
        ps = c.prepareStatement("UPDATE 2 ...");
    }
} 
catch (SQLException e) {
    log.error("Problem creating prepared statement, e );
    throw e;
}

// use
try {
    ps.executeUpdate();
} catch (SQLException e) {
    log.error("Problem decrementing palets on " + srcElement.getName() + 
        ": " +    e.getMessage());
}
finally {
    try {
        ps.close();
    } catch (SQLException e) {
        log.warn("Error closing PreparedStatement: " + e.getMessage());
    };
}
于 2013-02-13T20:58:35.317 に答える
-5

変数名を c から mC に変更します。変数名として c を使用している間、それは奇妙な不具合だと思います。ありがとうチャーリー

于 2014-12-16T16:28:46.003 に答える