こんにちは。「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()が呼び出されました。」と出力されます。