異常な
例外の原因
- Athrowバイトコード命令が実行されます。
- ときに異常バイトコード命令を実装した場合には、直ちに異常する仮想マシンのプログラムは、同期異常実装の発生を検出した後にスローされます。例えば:
Java仮想マシンで実行される各メソッドはそれ以上にゼロが装備される例外ハンドラ。例外ハンドラは、方法コード記述されている有効範囲は、扱うことができる例外の種類および例外処理コードの位置を。
現在の例外ハンドラは、任意の方法を見つけていない、そして現在は、オペランドスタック及びローカル変数テーブルの現在の方法が破棄されることを、メソッド呼び出し例外中に発生した場合は、その対応するスタックは、スタックフレーム、およびに戻りました呼び出し元のメソッドのスタックフレーム。未処理の例外は、呼び出し元のスタックフレーム方式で投げ、そしてチェーン全体のメソッド呼び出しでは、上記のプロセスを繰り返していきます。あなたはメソッド呼び出しの連鎖の頂点に達している場合は、まだ例外を処理するために、適切な例外ハンドラを見つけていない、実行の全体のスレッドが終了します。
クラスファイルに例外ハンドラを検索、各メソッドの例外ハンドラがテーブルに格納されている場合、検索順序が重要です。ランタイム、例外がスローされたとき、正面から、記述されたクラスファイル例外ハンドラテーブルの順序の例外ハンドラのJava仮想マシンが検索できます。
Java仮想マシン自体は、プロセスの例外ハンドラテーブルは、ソートまたはその他に対処することを余儀なくので、Java言語の例外テーブルを配置するのを支援するために、コンパイラ、適切な例外ハンドラによって、実際には、セマンティクスを処理しているではないだろう完了しました。
try-catch-ようやくの例
public class Test {
void testException(int i) {
try {
System.out.println(i);
} catch (NullPointerException e) {
throw new NullPointerException();
} catch (RuntimeException e) {
throw new RuntimeException();
} finally {
System.err.print(i);
}
}
}
コンパイルの上記の例javac Test.java
と逆コンパイルは、javap -c Test.class
バイトコード命令を生成します。
0: getstatic #2 // 获取第一个静态方法 println:Field java/lang/System.out:Ljava/io/PrintStream;
3: iload_1
4: invokevirtual #3 // 执行第一个静态方法 println:Method java/io/PrintStream.println:(I)V
7: getstatic #4 // 获取finally的静态方法 print:Field java/lang/System.err:Ljava/io/PrintStream;
10: iload_1
11: invokevirtual #5 // 执行finally的静态方法 print:Method java/io/PrintStream.print:(I)V
14: goto 45 // 跳到return指令结束程序
==========================
17: astore_2
18: new #6 // class java/lang/NullPointerException
21: dup
22: invokespecial #7 // Method java/lang/NullPointerException."<init>":()V
25: athrow
26: astore_2
27: new #8 // class java/lang/RuntimeException
30: dup
31: invokespecial #9 // Method java/lang/RuntimeException."<init>":()V
34: athrow
35: astore_3
36: getstatic #4 // Field java/lang/System.err:Ljava/io/PrintStream;
39: iload_1
40: invokevirtual #5 // Method java/io/PrintStream.print:(I)V
43: aload_3
44: athrow
==========================
45: return
Exception table: // 异常表,顺序和源码一致
from to target type
0 7 17 Class java/lang/NullPointerException //如果0-7之间有NullPointerException异常,跳到17
0 7 26 Class java/lang/RuntimeException //如果0-7之间有RuntimeException异常,跳到26
0 7 35 any //0-7之间任意情况下都会到35行,即finally
17 36 35 any //17-36之间任意情况下都会到35行,即finally