リファレンストップへ Java | try後の自動的なclose呼び出し使用した環境 JDK 7 Update 4 finallyを使って行っていたclose処理を自動化する事が可能ですJava6まではファイルの読み込みやDB接続など、処理の終了時に必ずclose()の呼び出しが必要となる場面では try ~ finally といったように、tryステートメントで処理全体を囲んだ上で finally内でclose()を呼び出すようなソースを書く必要がありました。 (Java6までの記述方法) BufferedReader br = null; try { br = new BufferedReader(new FileReader("d:/work/aaa.txt")); System.out.println(br.readLine()); } finally { if (br != null) { br.close(); } } Java7からは、下記のように簡略化できるようになりました。 try (BufferedReader br = new BufferedReader(new FileReader("d:/work/aaa.txt"))) { System.out.println(br.readLine()); } セミコロンで区切る事によって、複数の変数をclose()対象にする事もできます。 try (BufferedReader br = new BufferedReader(new FileReader("d:/work/aaa.txt")); BufferedReader br2 = new BufferedReader(new FileReader("d:/work/bbb.txt"))) { System.out.println(br.readLine()); System.out.println(br2.readLine()); } tryステートメント内での自動クローズですが、java.lang.AutoClosableインターフェイスを実装している クラスであれば利用する事ができます。 また、AutoClosable#closeは、finallyの直前に呼び出されます。 public class Test { public static void main(String[] args) throws Exception { System.out.println("begin"); try (CloseTest test = new CloseTest()) { System.out.println("process..."); } finally { System.out.println("finally"); } System.out.println("end"); } } class CloseTest implements AutoCloseable { @Override public void close() throws IOException { System.out.println("close()"); } } 実行結果は下記のようになります。 finally処理の直前にclose()メソッドがコールされている事が分かります。 begin process... close() finally end AutoCloseable#closeメソッド内でExceptionが発生した場合はそのままthrowされます。 この動作を検証するサンプルは下記の通りです。 1: import java.io.IOException; 2: 3: 4: public class Test { 5: 6: 7: public static void main(String[] args) throws Exception { 8: 9: System.out.println("begin"); 10: 11: try (CloseTest test = new CloseTest()) { 12: System.out.println("process..."); 13: 14: } finally { 15: System.out.println("finally"); 16: 17: } 18: 19: System.out.println("end"); 20: 21: } 22: 23: } 24: 25: class CloseTest implements AutoCloseable { 26: 27: @Override 28: public void close() throws IOException { 29: throw new IOException("test of Exception"); 30: 31: } 32: 33: 34: } 実行結果は下記のようになります。 begin process... finally Exception in thread "main" java.io.IOException: test of Exception at CloseTest.close(Test.java:30) at Test.main(Test.java:14) スタックトレースを見てみると、Test.java:14となっており、finallyの直前でExceptionが投げられた扱いになっている事が分かります。 また、AutoCloseable#close内でExceptionが投げられた場合であっても、親ルーチン内のfinallyが呼び出されている事が分かります。 |
|