本題
昨日のこのタイトルとほぼ同名の記事を書いた後にさくらばさんに
アドバイスもらいました。
@mike_neck ヒント http://ow.ly/bSyBt
— Yuichi Sakurabaさん (@skrb) 6月 28, 2012
おお、そういえば、いろふさんのブログにもあったような…
Throwable#getSuppressed()
なるものがあって、最初に投げられた例外にそのあとに投げられた例外が保存されているようです。
気を取り直して
昨日のコードを書きなおしてみました。
catch
の部分で他に例外がsuppressされていないか確認してみました。で、実行結果がこれです。
メソッド実行中とクローズ中に発生した例外について、
メソッド実行中の例外にクローズ中に発生した例外がsuppressされているのが確認できます。
実際、どうなってんの?
さて、さくらばさんからこんなアドバイスももらっています。
@mike_neck try...with...resourcesをデコンパイルしてみると、おもしろいですよ。Suppressedがどうやって使われているか分かります。
— Yuichi Sakurabaさん (@skrb) 6月 28, 2012
というわけで、デコンパイルしてみようとしたらJDってツールがダウンロード出来ない…(´・ω・`)
Jadの方をダウンロードしてデコンパイルしてみました。
ところどころ残念なことになってはいますが、まあ読めますね。
メソッド実行中とクローズ中の例外に例外が発生するパターンでは…
- 52行目の
try
からが本来のtryに該当するところで、55行目のact.something()
で例外が発生。 - 63行目と64行目の条件はtrueになるので、67行目の
act.close()
を実行して例外が発生。 - 二度目に発生した例外は69行目の
catch
で捕まって、71行目で最初に発生した例外にaddSuppressed(java.lang.Throwable)
される。 - 76行目以降の同じようなコードはここまで例外が発生しなかった場合のauto
close()
処理ですかね。 - 92行目以降の
e;
ってなってるのは本来のJavaコードのcatch
部分で、各例外のハンドリングが実施される。
といった感じでしょうか。
なるほど、こういう風にコンパイル時にコードが展開されるんですね。
副作用
というわけで、昨日の記事を訂正したんですが、
どうやらバイトコードに興味を持ちました。
で、そういったあたりをTwitterで呟いたら
@mike_neck それは当然ですよw Javaやっているのに、バイトコード知らないなんてありえないじゃないですかwwww そういえば、Facebookでコメントしたんだけど、invoke dynamicじゃなくて、invokedynamicです。
— Yuichi Sakurabaさん (@skrb) 6月 29, 2012
ツイッター怖っ!