try-with-resourcesメカニズムは、リソース(入力・出力ストリームやデータベース接続など)の自動管理のためにJava7で導入されました。これによりリソースの取り扱いが簡素化され、リークのエラーが最小限に抑えられます。
背景:
Java7以前は、リソースを手動でfinallyブロックで閉じる必要があり、コードの重複やエラーの原因になっていました。try-with-resourcesによってこのプロセスが自動化され、コードがクリーンで安全になりました。
問題点:
リソースが明示的に閉じられない場合、リークが発生する可能性があります(例:ファイルハンドルやデータベース接続が解放されないなど)。古い方式では、特に複数の例外が発生する場合にfinallyブロックでclose()を呼び出すことを忘れることがよくありました。
解決策:
リソースがAutoCloseableインターフェースを実装している場合は、常にtry-with-resourcesを使用します。
使用例:
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) { String line = reader.readLine(); // ... } catch (IOException e) { e.printStackTrace(); }
tryブロックを出る際にclose()が自動的に呼び出され、リソースの適切な解放が保証されます。
主な特徴:
複数のリソースを使ったtry-with-resourcesは可能ですか?
はい、セミコロンを使って1行に複数のリソースを宣言できます:
try ( InputStream in = new FileInputStream("a.txt"); OutputStream out = new FileOutputStream("b.txt") ) { // ... }
try-with-resourcesで例外を捕捉することは必須ですか?
いいえ、メソッドで例外をスローする旨が宣言されている場合や処理が必要ない場合はcatchを指定する必要はありませんが、正確な診断のためにcatchが必要な場合が多いです。
try()の外で宣言された変数をtry-with-resourcesのリソースとして使用できますか?
いいえ、リソースは必ずtryの括弧内で宣言する必要があります。さもなければ自動的なクローズは機能しません。
コードがtry-with-resourcesなしでFileInputStreamを開き、開発者がストリームを閉じるのを忘れたり、エラーがない場合のみ閉じたりします。例外が発生すると、ストリームが閉じられません。
利点:
欠点:
try-with-resourcesが使用され、リソースはtryの括弧内に直接宣言され、解放が常に保証されます。
利点:
欠点: