2013-07-22 7 views
15

次のコードでtry-with-resourcesを正しく使用するかどうかは疑問です。Java暗黙のtry-with-resources

try (ResultSet rs = new QueryBuilder(connection, tableName(), getPaths(), searchQuery()).add(constraint).build().executeQuery()) { 
    while (rs.next()) { 
     beans.add(createBean(rs)); 
    } 
} 

引数は重要ではない、唯一重要なことは、次のとおりです。

  • new QueryBuilder().build();PreparedStatementを返します。

私は完全にrsが閉鎖されることを理解し、しかしPreparedStatementも閉鎖され、そうであれば、どのような理由のために? ResultSetがリソースを試行したり終了したりするために終了したためですか?

答えて

19

PreparedStatement#close()は、関連する結果セットを自動的に閉じますが、結果セットが閉じられた後でステートメントを再利用できるため、その逆は真ではありません。 ResultSet#close()のjavadocので

ルック:

注: ResultSetオブジェクトが自動的にそのStatementオブジェクトが

そしてStatement#close()を閉じているときに、それを生成したStatementオブジェクトによって閉鎖されています。

注: Statementオブジェクトがクローズされると、現在のResultSetオブジェクト(存在する場合)もクローズされます。

この用法は、私には非常に安っぽいです:

ResultSet rs=conn.createStatement().executeQuery(); 

十分な回数を実行した場合、カーソルがResultSetStatementないに関連付けられているので、それは、可能なすべてのカーソルをリークします。

そこでちょうどtry文の中でそれを宣言し、try-with-resources statementとの根本的なPreparedStatementを閉じます:

のtry-と資源文が実行前に初期化されます(リソースとして知られている)の変数とパラメータ化されています自動的に閉じられた

this answer from assyliasを見て、try文の中PreparedStatementなどResultSetを宣言します。

のメモリリークは探していませんが、リソースリークはです。 PreparedStatementのメモリは最終的に収集され、メモリは解放されます。ただし、初期化の方法を指定してメソッドの実行後に参照されなくなるため、Statementによって保持されるリソースは閉じられません。

2

正しく記載されているとおり、rsは閉鎖されます。これは実際にclose()メソッドがrsで呼び出されることを意味します。したがって、try-with-ressourceステートメントは、あなたのケースではPreparedStatementを明白に終了しません。 @TheNewIdiotが正しく、あなたのPreparedStatementウォン」を見つけたとして

それは(rs.close()の文脈で)そうでない場合は閉じていた場合は実装;-)

EDIT

を知らずに言うのは難しいの一種であります閉鎖する。

9

あなたは試しにいくつかのリソースを含めることができ、そしてそれらはすべて閉じられます - あなたはPreparedStatementを閉じることにしたい場合に必要である:、

try (PreparedStatement ps = new QueryBuilder(connection, tableName(), getPaths(), searchQuery()).add(constraint).build(); 
     ResultSet rs = ps.executeQuery();) { 
    while (rs.next()) { 
     beans.add(createBean(rs)); 
    } 
} 
+0

私はそれを持っていました(そしてもう一度やります)しかし、私はtwを避けようとしていました異なる宣言。 – skiwi

+0

+1あなたはそれに私を打ち負かしました:-) –

+0

@skiwi私は実際には2つのステートメントをより読みやすく、それ以下に分割しています。 – assylias

3

ドキュメントhere - tryResourceCloseによると、私はそれを読んでそれはdeclaredであるリソースに固有です。さらに下の読み込み

The try-with-resources statement is a try statement that declares one or more resources.

あなたは以下を参照してください。

You may declare one or more resources in a try-with-resources statement. The following example retrieves the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files:

try (
     java.util.zip.ZipFile zf = 
     new java.util.zip.ZipFile(zipFileName); 
    java.io.BufferedWriter writer = 
     java.nio.file.Files.newBufferedWriter(outputFilePath, charset) 
) { 

私はあなたに正しい答えを示唆して発行する次のとおりです。

try{ 
    PreparedStatement statement = new QueryBuilder(connection, tableName(), getPaths(), searchQuery()) 
     .add(constraint).build(); 
    ResultSet rs = statement.executeQuery()) 
}