try-catch-finally塊的實現原理
阿新 • • 發佈:2019-02-02
程式碼片段1
public class TestMain {
public static void main(String[] args) {
try {
String A="hello world !";
}catch (Exception e){
e.printStackTrace ();
}
finally {
System.out.println ( "nihao" );
}
}
}
位元組碼
Compiled from "TestMain.java"
public class TestMain {
public TestMain();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String hello world !
2: astore_1
3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
6: ldc #4 // String nihao
8: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
11: goto 41
14: astore_1
15: aload_1
16: invokevirtual #7 // Method java/lang/Exception.printStackTrace:()V
19: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
22: ldc #4 // String nihao
24: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
27: goto 41
30: astore_2
31: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
34: ldc #4 // String nihao
36: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
39: aload_2
40: athrow
41: return
Exception table:// 異常表
from to target type
0 3 14 Class java/lang/Exception//0-3號指令中,碰到 Exception 時,跳到 14 號指令
0 3 30 any
14 19 30 any
}
異常表
屬性表(attribute_info)可以存在於 Class 檔案、欄位表、方法表中,用於描述某些場景的專有資訊。屬性表中有個 Code 屬性,該屬性在方法表中使用,Java 程式方法體中的程式碼被編譯成的位元組碼指令儲存在 Code 屬性中。而異常表(exception_table)則是儲存在 Code 屬性表中的一個結構,這個結構是可選的。
異常表結構
異常表結構如下表所示。它包含四個欄位:如果當位元組碼在第 start_pc 行到 end_pc 行之間(即[start_pc, end_pc))出現了型別為 catch_type 或者其子類的異常(catch_type 為指向一個 CONSTANT_Class_info 型常量的索引),則跳轉到第 handler_pc 行執行。如果 catch_type 為0,表示任意異常情況都需要轉到 handler_pc 處進行處理。
型別 | 名稱 | 數量 |
---|---|---|
u2 | start_pc | 1 |
u2 | end_pc | 1 |
u2 | handler_pc | 1 |
u2 | catch_type | 1 |