ThrowableクラスのgetSuppressedメソッドについて
Java7でThrowableクラスにgetSuppressedメソッドが追加になっています。これはtry-with-resourcesを利用した際にたとえば複数リソースのクローズ時に複数の例外が発生した場合、catchブロックでSuppressされた例外を取得する際などに利用します。
try (Resource1 f = new Resource1(); Resource2 s = new Resource2()) { // 何らかの処理 } catch (Exception e) { e.printStackTrace(); for (Throwable t : e.getSuppressed()) { t.printStackTrace(); } }
Resource1、Resource2クラスのcloseメソッド内で意図的に例外を発生させるように記述。
public class Resource1 implements AutoCloseable { ... @Override public void close() throws Exception { System.out.println("invoked close on " + getClass().getSimpleName()); throw new IllegalStateException("first"); } }
public class Resource2 implements AutoCloseable { ... @Override public void close() throws Exception { System.out.println("invoked close on " + getClass().getSimpleName()); throw new IllegalStateException("second"); } }
try-with-resourcesでリソースの自動解放を行うにはAutoClosableインターフェースを実装している必要があります。以前このブログでtry-with-resourcesについて書いた時に、Closableインターフェースを実装云々と記載しましたが正確にはAutoClosableのようです。
プログラムを実行するとcloseメソッド内から発生したそれぞれの例外のスタックトレースを出力しているのがわかると思います。同時にtry-with-resourcesでは最初にリソースをオープンしたのとは逆順にcloseメソッドが実行されているのもわかると思います。getSuppressedメソッドで取得するSuppressされた例外もこの順番で返されます。
したがって出力されるスタックトレースもResource2のcloseで発生した例外が先に出力され、次にResource1のcloseで発生した例外が出力されます。