2010年8月21日土曜日

Java7のjavac新機能を試した

jdk1.7.0 b105でARM(Automatic Resource Management/try-with-resources)が入ったので試してみた。
リソースを自動で閉じてくれるもので、Pythonとかのwithみたいな感じに使える。
ARMで自動で閉じられるようにするには、java.lang.AutoCloseableを実装している必要がある
ARMはclose/finallyより使う側の負荷が低いのでよいと思う。

理由

  • 使う側のコード量が少なくなる
  • コードが少なくなる理由でもあるが、複数のリソースを確実に閉じられる。

試しに作ってみたもの。マルチキャッチも使ってみた。

public class Test {
  private static class AC implements AutoCloseable {
    public void close() throws java.io.IOException {
      throw new java.io.IOException();
    }
  }

  private static class AC2 implements AutoCloseable {
    public void close() throws InterruptedException {
      throw new InterruptedException();
    }
  }

  public static void main(String... args) {
    try {
      try(AC ac = new AC(); AC2 ac2 = new AC2()) { }
    } catch (final java.io.IOException | InterruptedException e) {
      e.printStackTrace();
    }
  }
}

これを実行すると

java.lang.InterruptedException
        at Test$AC2.close(Test.java:10)
        at Test.main(Test.java:16)
        Suppressed: java.io.IOException
                at Test$AC.close(Test.java:4)
                ... 1 more

AC1, AC2がそれぞれブロックを抜けるときのcloseで例外を投げるが、とりあえず全部closeされる。

ここでcloseが投げる例外が無ければ外側のtry/catchは不要だし、
例外に継承関係があれば(java.io.IOExceptionとjava.io.FileNotFoundExceptionとか)があれば親側でcatchするのでも可能。

追記
finallyの場合RuntimeExceptionでもfinallyは実行されるので、ARMではどうか確認したら、途中でRuntimeExceptionが起きた場合もちゃんと全部closeが呼び出された。
これならfinallyでRuntimeExceptionが発生して、全部後処理しきれないとかの問題は回避できるな。



0 件のコメント:

コメントを投稿