Keep it simple, stupid!!

IT系で調べたこととか考えたこととか書くつもりです。

try-with-resourcesと等価コード

try-with-resourcesの使い方を昨日初めて知りましたorz
残念なあまりバイトコードまで読んで等価のコードを読み取ってみたよ*1

とりあえず

try (InputStream input = new FileInputStream("ファイル.txt")) {
    // 処理
}

な書き方ができるのがtry-with-resources
いままでは

InputStream input = new FileInputStream("ファイル.txt");
try {
    // 処理
} finally {
    input.close();
}

って書いてたね*2

でもこの二つは等価じゃないみたい。

バイトコードから読み取った感じだと、

Throwable e1 = null;
Throwable e2 = null;
try {
	InputStream input = new FileInputStream("ファイル.txt");
	try {
		// 処理
	} catch (Throwable e) {
		e1 = e;
		throw e1;
	} finally {
		if (input != null) {
			input.close();
		}
	}
} catch (Throwable e) {
	e2 = e;
	if (e1 == null) {
		e1 = e2;
	} else {
		if (e1 == e2) {
			e1.addSuppressed(e2);
		}
	}
	throw e1;
}

のような感じ。

#超厳密にいうと、変数宣言*3とtry catch finallyの範囲の指定*4javaコードから書くのはたぶん不可能だったりする。
基本的にバイトコードのほうが効率的になっている

*1:間違ってる可能性大

*2:ええ僕は一昨日まで書いてましたよorz

*3:Throwable eという変数はバイトコードには存在しない。
次の行でe1、e2に代入しているがバイトコードではcatchで直接代入している。

} catch (e2) {
っとか書きたい。e1の扱いはなかなか難しい。

*4:input.close()前のfinallyは本当はfinallyではないし、catchの書き方も厳密には違う(どういうコード書いたらそういうバイトコードになるのかわからない。)
記載したコードは残念ながらgotoとfinally扱いがいくつか多くなる。