jdk7のリソース管理
先日リリースされたjdk7。
あまり大きな変更点は無いのかな?
気になるのはStringのswitch、AutoCloseale、ジェネリクスコンストラクタの簡略化くらいか。
早速AutoCloseableを試してみた。
import java.io.*; public class Main { public static void main(String[] args) { try { try (FileInputStream fis = new TestStream1("Main.java") ; InputStreamReader isr = new InputStreamReader(fis) ; BufferedReader br = new BufferedReader(isr)) { System.out.println(br.readLine()); } } catch (Exception e) { e.printStackTrace(); System.exit(1); } } public static class TestStream1 extends FileInputStream { public TestStream1(String fileName) throws IOException { super(fileName); } public void close() throws IOException { new Exception().printStackTrace(); System.out.println(); super.close(); } } }
で、こうなる。
import java.io.*; java.lang.Exception at Main$TestStream1.close(Main.java:25) at sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:377) at sun.nio.cs.StreamDecoder.close(StreamDecoder.java:192) at java.io.InputStreamReader.close(InputStreamReader.java:199) at java.io.BufferedReader.close(BufferedReader.java:517) at Main.main(Main.java:11) java.lang.Exception at Main$TestStream1.close(Main.java:25) at Main.main(Main.java:11)
こうすると、
import java.io.*; public class Main { public static void main(String[] args) { try { try (FileInputStream fis = new TestStream1("Main.java") ; InputStreamReader isr = new InputStreamReader(fis) ; BufferedReader br = new BufferedReader(isr)) { System.out.println(br.readLine()); } } catch (Exception e) { e.printStackTrace(); System.exit(1); } } public static class TestStream1 extends FileInputStream { public TestStream1(String fileName) throws IOException { super(fileName); } public void close() throws IOException { new Exception().printStackTrace(); System.out.println(); if (true) { throw new IllegalArgumentException(""); } super.close(); } } }
こうなる。
import java.io.*; java.lang.Exception at Main$TestStream1.close(Main.java:25) at sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:377) at sun.nio.cs.StreamDecoder.close(StreamDecoder.java:192) at java.io.InputStreamReader.close(InputStreamReader.java:199) at java.io.BufferedReader.close(BufferedReader.java:517) at Main.main(Main.java:11) java.lang.Exception at Main$TestStream1.close(Main.java:25) at sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:377) at sun.nio.cs.StreamDecoder.close(StreamDecoder.java:192) at java.io.InputStreamReader.close(InputStreamReader.java:199) at Main.main(Main.java:11) java.lang.Exception at Main$TestStream1.close(Main.java:25) at Main.main(Main.java:11) java.lang.IllegalArgumentException: at Main$TestStream1.close(Main.java:28) at sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:377) at sun.nio.cs.StreamDecoder.close(StreamDecoder.java:192) at java.io.InputStreamReader.close(InputStreamReader.java:199) at java.io.BufferedReader.close(BufferedReader.java:517) at Main.main(Main.java:11) Suppressed: java.lang.IllegalArgumentException: at Main$TestStream1.close(Main.java:28) at sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:377) at sun.nio.cs.StreamDecoder.close(StreamDecoder.java:192) at java.io.InputStreamReader.close(InputStreamReader.java:199) ... 1 more Suppressed: java.lang.IllegalArgumentException: at Main$TestStream1.close(Main.java:28) ... 1 more
なるほど。
closeの中でエラーが出てもすべてのcloseが呼ばれる、と。
すべてのエラーはThrowable#getSuppressed()で取得できる、と。
最初に出たExceptionが直接コードから見えるものになる、と。