异常处理表
字节码的Code属性中有 异常处理表
exception_table {
u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
}
含4个字段,这些字段的含义为:如果当字节码在第start_pc行到第end_pc行之间(不包含end_pc行)
出现了类型为catch_type或者其子类的异常(catch_type为指向一个CONSTANT_Class_info型常量的索引),
则转到第handler_pc行继续处理。当catch_type的值为0时,代表任意异常情况都需要转向到handler_pc处进行处理
测试代码
public int inc() {
int x;
try {
x = 1;
return x;
} catch(Exception e) {
x = 2;
return x;
} finally {
x = 3;
}
}
使用jclasslib bytecode viewer 查看编译后的字节码
0 iconst_1 // try中 x=1
1 istore_1
2 iload_1 // 保存x到returnValue中,此时x=1
3 istore_2
// 4-5行是finally
4 iconst_3 // finally块中x=3,推送栈顶
5 istore_1
6 iload_2 //将returnValue中值放到栈顶,准备给ireturn返回
7 ireturn
8 astore_2 // 给catch中的Exception e赋值,存储在Solt2中
9 iconst_2 // catch中的x=2
10 istore_1
11 iload_1 // 保存x到returnValue中,此时x=2
12 istore_3
// 13-14行是finally
13 iconst_3 // finally块中x=3,推送栈顶
14 istore_1
15 iload_3 //将returnValue中值放到栈顶,准备给ireturn返回
16 ireturn
17 astore 4 // 如果出现了不属于java.lang.Exception及其子类的异常,会走这
19 iconst_3 // finally块中x=3,推送栈顶
20 istore_1
21 aload 4 // 将异常送至栈顶
23 athrow // 抛出一个异常实例(exception 或者 error)