java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

try-with-resources文

投稿日:

最終更新日:2016年08月29日

アイキャッチ

こんにちは。「Javaを復習する初心者」です。

今回はtry-with-resources文について復習しました。

try-with-resources文を使うと、リソースの開放が必要な処理の記述が簡略化できます。

リソースの開放が必要な例

最初にtry-catch文でリソースの開放が必要な例を復習しました。close()メソッドの呼び出しが行われたかを確認するために、まず、BufferedReaderExというクラスを作りました。

BufferedReaderEx

public class BufferedReaderEx extends BufferedReader {

    public BufferedReaderEx(Reader in) {
        super(in);
    }

    @Override
    public void close() throws IOException {
        System.out.println("close()メソッドがコールされました。");
        super.close();
    }

}

BufferedReaderを継承したクラスです。close()メソッドが呼ばれたときに、「close()メソッドがコールされました。」というメッセージをコンソールに出力し、親クラスのclose()メソッドを呼び出します。このクラスを使い、close()メソッドが呼び出されたのかを確認します。

以下はtry-catch文でclose()メソッドを呼び出す例です。finally節でclose()メソッドを呼び出します。

try-catch文

public class HelloTryCatchFinally {

    public static void main(String[] args) {

        File file = new File("resource\\sample.txt");
        BufferedReaderEx br = null;
        try {
            br = new BufferedReaderEx(new FileReader(file));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);;
             }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

resource/sample.txtには「Hello」という文字列が保存されています。このファイルを読み取り、コンソールに出力するプログラムです。結果は以下の通りです。

結果

Hello
close()メソッドがコールされました。

finally節は例外の発生有無にかかわらず実行されます。なのでclose()メソッドが呼び出されます。ところでBufferedReaderExの宣言がなぜtry節の中ではないのかというと、finally節で使うためです。中括弧でブロックと呼ばれるスコープの範囲を表します。finally節の中からはtry節で宣言された変数は使えません。

try-with-resources文

さて、java1.7からはtry-with-resources文が使えます。以下のような書き方です。

try-with-resources

        File file = new File("resource\\sample.txt");
        try (BufferedReaderEx br = new BufferedReaderEx(new FileReader(file))){
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);;
             }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

「try ([リソースの宣言])」という書き方をします。この部分で宣言した変数に対して、自動的にclose()メソッドが呼び出されます。なので実行結果は同じです。BufferedReaderEx#close()メソッド呼び出され、コンソールに「close()メソッドがコールされました。」と出力されます。

リソースの宣言の箇所は複数の変数を宣言できます。その場合、セミコロンで区切ります。

自作クラスを記述

リソースの宣言の箇所に自作クラスを記述したい場合、Closeableインターフェースを実装する必要があります。以下は簡単な例です。

実装例

public class MyClass implements Closeable {

    @Override
    public void close() throws IOException {
        System.out.println("MyClass#close()が呼び出されました。");
    }

}

このクラスを使って次のようにtry-with-resources文を使うことができます。

ソース

        try (MyClass myClass = new MyClass()){
        } catch (Exception e) {
            e.printStackTrace();
        }

上記を実行するとコンソールに「MyClass#close()が呼び出されました。」と出力されます。