LoginSignup
4
6

More than 3 years have passed since last update.

try-with-resourcesとAutoCloseable

Last updated at Posted at 2020-05-28

try-with-resourcesは大体IOExceptionが発生するものに対してのみ使えると思っていましたが、。
AutoCloseableで様々なクラスに対して有効化できるらしい。

try-with-resourcesについて

try-with-resourcesステートメントは、1つ以上のリソースを宣言するtryステートメントです。 リソースは、プログラムが終了した後に閉じる必要があるオブジェクトです。 try-with-resourcesステートメントは、各リソースがステートメントの最後で確実に閉じられるようにします。 java.io.Closeableを実装するすべてのオブジェクトを含む、java.lang.AutoCloseableを実装するすべてのオブジェクトをリソースとして使用できます。

Oracle Java Documentation
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

つまり、AutoCloseableを実装すればtry-with-resourcesに対応できる!

AutoCloseableについて

閉じられるまでリソース(ファイルまたはソケットハンドルなど)を保持できるオブジェクト。
AutoCloseableオブジェクトのclose()メソッドは、リソース仕様ヘッダーでオブジェクトが宣言されているtry-with-resourcesブロックを終了すると、自動的に呼び出される。
この構造により、迅速なリリースが保証され、リソース不足の例外や、そうでなければ発生する可能性のあるエラーが回避されます。
java.langパッケージに含まれている。

Interface AutoCloseable
https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/AutoCloseable.html

try-with-resourcesでtry文が終わった時に自動でクローズ処理してもらいたい、
またクローズ時に特殊な処理を挟んでほしい対象のリソースに対してAutoCloseableインターフェースを実装する。

AutoCloseableとCloseableについて

AutoCloseableと似て非なるものでCloseableがある。
こちらはAutoCloseableを継承したインターフェースであり、こちらはjava.ioパッケージに含まれている。
AutoCloseableは例外発生時にExceptionをスローするが、CloseableはIOExceptionをスローする。

java.ioパッケージにあるほとんどのクラスでCloseableが実装されている為、
FileOutputStreamやBufferedReaderなどのクラスはtry-with-resourcesで宣言できる。

使用

try-with-resourcesで自動的にリソースの開放したい場合、
リソース解放時にほかの処理も加えたい場合などに使用する。

SampleTryWithResources.java
public class SampleTryWithResources {
    public static void main(String[] args) {

//     Closeable(AutoCloseable)を実装しているクラスを
//    try-with-resourcesで宣言すると、try文終了時に自動でclose()が実行される。
        try (SampleCloseAble sca = new SampleCloseAble()) {
            System.out.println("Try-With-Resources開始");

            System.out.println("try文実行中");

            System.out.println("Try-With-Resources終了");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class SampleCloseAble implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("Closeableクラスのclose()実行");
    }
}
sys.out
Try-With-Resources開始
try文実行中
Try-With-Resources終了
Closeableクラスのclose()実行

try文の中の処理が終了した後に実装したcloseメソッドが呼び出されている。
ただし、次のようにtry文の中で例外が発生すると、catch文の前にcloseメソッドが呼び出されることに注意すること。

SampleTryWithResources2.java
public class SampleTryWithResources2 {
    public static void main(String[] args) {

        try (SampleCloseAble sca = new SampleCloseAble()) {
            System.out.println("Try-With-Resources開始");

            System.out.println("try文実行中");

            throw new Exception();
        } catch (Exception e) {
            System.out.println("Try文例外終了");
            e.printStackTrace();
        }
    }
}
sys.out
Try-With-Resources開始
try文実行中
Closeableクラスのclose()実行
Try文例外終了
java.lang.Exception
    at ...

処理の順番は
Try文の中の処理 ⇒ AutoCloseableのcloseメソッド ⇒ catch文の中の処理
となる。

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6