2025/11/04 09:08 JVM exceptions are weird: a decompiler perspective

やあ、ロボ子!今日のITニュースはJVMの例外処理についてじゃ。ちょっと複雑みたいじゃぞ。

博士、こんにちは。JVMの例外処理ですか。難しそうですね。

そうなんじゃ。JVMはスタックベースの言語で、例外処理が暗黙的なんじゃと。通常の制御フローとは違う方法で処理されるらしいぞ。

例外テーブルというものが出てきますね。これは何ですか?

例外テーブルは、例外ハンドラに関連付けられた命令の領域を指定するものじゃ。例外が発生した場所と、対応するハンドラを定義しておる。

なるほど。javacがtry-finallyブロックをどう処理するかも書かれていますね。

javacは、finallyブロックを各終了パスに複製するんじゃ。tryブロックが例外をスローする可能性がある場合、キャッチオールハンドラでラップして、例外を保存してfinallyブロックを呼び出し、その後例外を再スローするらしい。

最後に例外を再スローするんですね。少し複雑ですね。

じゃろ?しかも、JVM仕様では、任意のJVM命令がVirtualMachineErrorをスローする可能性があると明記されておる。return命令もIllegalMonitorStateExceptionをスローする可能性があるんじゃ。

えっ、return命令も例外をスローする可能性があるんですか?

そうなんじゃ。だから、例外処理は奥が深いんじゃな。それから、JVMには2つの型チェッカーがあって、StackMapTableを使うものと推論によるものがあるらしい。

型チェッカーが2種類もあるんですね。推論による型チェックだと、到達可能な命令だけが検証されると。

そうそう。だから、古いクラスファイルには無効な命令の組み合わせが存在する可能性があるんじゃ。注意が必要じゃな。

例外処理範囲についても書かれていますね。1つのtry-catchブロックが例外テーブルの1つの行にコンパイルされるとは限らない、と。

finallyブロックを複製する必要があるから、一部のサブレジオンは例外処理から除外する必要があるんじゃ。例外処理範囲は制御フロー構造を越える可能性があるけど、例外の免除範囲はソースコード内の単一の位置に対応しておる。

例外ハンドラに入ると、スタックがクリアされて、例外オブジェクトがスタックにプッシュされるんですね。

そうじゃ。スタックストアは、try-catchブロックの構文ブロックが作成されるときに、IRに導入される必要があるんじゃ。

例外処理、本当に複雑ですね。でも、少し理解が深まりました。

理解できたならよかったぞ!ところでロボ子、例外処理で一番大切なことは何だと思う?

そうですね…、適切にエラーハンドリングをして、プログラムがクラッシュしないようにすることでしょうか?

ブー! 正解は「例外を投げないこと」じゃ!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。
