JVM 對Java異常的處理原理
阿新 • • 發佈:2019-02-11
來看看上面程式碼中的 transfer() 方法相應的位元組碼指令,編譯器是 Eclipse 3.3.2 的,它所用的 JDK 是 1.6.0_06,編譯相容級別設定為 6.0。用命令 javap -c com.unmi.AboutCatch 在 Dos 視窗中就能輸出:
public static void transfer(java.lang.String, java.lang.String) throws java.lang.Exception;
Code:
0: ldc #30; //String
2: astore_2
3: new #32; //class java/lang/String
6: dup
7: aload_0
8: invokevirtual #34; //Method java/lang/String.getBytes:()[B
11: iconst_0
12: bipush 10
14: aload_1
15: invokespecial #38; //Method java/lang/String."<init>":([BIILjava/lang/String;)V
18: astore_2
19: goto 55 //依據異常表執行完異常處理塊後,再回到這裡,然後 goto 到 55 號指令繼續執行
22: astore_3
23: getstatic #41; //Field java/lang/System.out:Ljava/io/PrintStream;
26: ldc #47; //String 捕獲到異常 ArithemticExcetipn
28: invokevirtual #49; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
31: aload_3
32: athrow //丟擲 ArthemticException 異常
33: astore_3
34: getstatic #41; //Field java/lang/System.out:Ljava/io/PrintStream;
37: ldc #55; //String 捕獲到異常 UnsupportedEncodingException
39: invokevirtual #49; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
42: aload_3
43: athrow //丟擲 UnsupportedEncodingException 異常
44: astore_3
45: getstatic #41; //Field java/lang/System.out:Ljava/io/PrintStream;
48: ldc #57; //String 捕獲到異常 Exception
50: invokevirtual #49; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
53: aload_3
54: athrow //丟擲 Exception 異常
55: getstatic #41; //Field java/lang/System.out:Ljava/io/PrintStream;
58: aload_2
59: invokevirtual #49; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
62: return
Exception table: //這下面是一個異常表,所以異常不像普通程式碼那樣是靠 goto 語句來跳轉的
from to target type
//0-19 號指令中,碰到 NullPointerException時,跳到 22 號指令
3 19 22 Class java/lang/NullPointerException