65
64

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

アルス・ウェアーAdvent Calendar 2018

Day 4

try-finallyよりもtry-with-resourcesを使おう

Last updated at Posted at 2018-12-03

try-finallyでのリソースクローズ

tryブロックの中で何らかのリソース(InputStream、OutputStream、BufferedReader等)を扱う場合、Java7以前はfinallyブロックでcloseメソッドを呼び出すことで、tryブロック内の処理が正常終了したか異常終了したかに関わらずリソースが確実に閉じられることを保証していました。以下のような形です。

.java
protected void copy(String src, String dest) throws IOException {
	InputStream in = new FileInputStream(src);
	try {
		OutputStream out = new FileOutputStream(dest);
		try {
			byte[] buf = new byte[100];
			int n;
			while ((n = in.read(buf)) >= 0) {
				out.write(buf, 0, n);
			}
		} finally {
			out.close();
		}
	} finally {
		in.close();
	}
}

また、finallyブロックで例外が発生しないよう更にチェックしたり等もありますよね。

.java
} finally {
	if (br != null)
		try {
			br.close();
		} catch (IOException e) {
			// 例外処理
		}
}

ただし、これらの書き方にはいくつか問題点があります。

try-finallyでのリソースクローズの問題点

  • close処理を色々な箇所で行ったりリソースのnullチェックを行ったり等コードが冗長となる
  • tryブロックの中とfinallyブロックの中の両方で例外が発生した場合、finallyブロックの中で発生した例外がスローされる(本来tryブロックの中で発生した例外が知りたいはずだが、その例外は抑制される)

こういった問題に対して、Java7でtry-with-resources構文が導入されました。try-with-resources構文によりこれらの問題は一挙に解決されます。

try-with-resourcesでのリソースクローズ

tryのすぐ後ろにクローズの対象となるリソースの生成処理を記述します。クローズすべきリソースが複数ある場合はセミコロンで区切ります。

.java
protected void copy(String src, String dest) throws IOException {
	try (InputStream inputStream = new FileInputStream(src); OutputStream outputStream = new FileOutputStream(dest)) {
		byte[] buf = new byte[100];
		int n;
		while ((n = in.read(buf)) >= 0) {
			out.write(buf, 0, n);
		}
	}
}

このように書くことで以下のような挙動になります。

  • finallyブロックでcloseメソッドを呼び出さなくても自動でcloseをしてくれるようになる(ソースが簡潔になり可読性が向上する)
  • close処理内で例外が発生してもtry文の中の例外がスローされる(本来知りたいはずの例外がスローされる)

これにより「try-finallyでのリソースクローズの問題点」で挙げた問題点が解決されます。

教訓

クローズしなければならないリソースを扱う場合は、try-finallyよりもtry-with-resourcesを使おう

参考

65
64
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
65
64

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?