目录
从字节码角度来分析:异常处理
1.1 异常-catch
// 从字节码角度来分析:异常处理
public class T13_ByteAnalyseException {
public static void main(String[] args) {
int i = 0;
try {
i = 10;
} catch (Exception e) {
i = 20;
}
}
}
注意:为了抓住重点,下面的字节码省略了不重要的部分
上述代码通过:javap -v T13_ByteAnalyseException.class进行反编译,得到如下字节码。
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=3, args_size=1
0: iconst_0
1: istore_1
2: bipush 10
4: istore_1
5: goto 12
8: astore_2 // 将异常对象引用存入局部变量表的 slot 2号位置
9: bipush 20
11: istore_1
12: return
Exception table: // 异常表,含头不含尾;一旦2~4行代码异常就进入异常判断是否是声明的Exception异常一致,如果一致就进入第8行
from to target type
2 5 8 Class java/lang/Exception
LineNumberTable:
line 15: 0
line 17: 2
line 20: 5
line 18: 8
line 19: 9
line 21: 12
LocalVariableTable:
Start Length Slot Name Signature
9 3 2 e Ljava/lang/Exception;
0 13 0 args [Ljava/lang/String;
2 11 1 i I
StackMapTable: ...
上述说明:
可以看到多出来一个Exception table的结构,[from, to)是前闭后开的检测范围,一旦这个范围内的字节码执行出现异常,则通过type匹配异常类型,如果一致,进入target所指示行号
8行的字节码指令 astore_2 是将异常对象引用存入局部变量表的 slot 2号位置
1.2 异常-多个catch
先来看下异常-多个catch代码示例:
// 从字节码角度来分析:多个 single-catch 块的情况
public class T14_ByteAnalyseMoreSingle_Catch {
public static void main(String[] args) {
int i = 0;
try {
i = 10;
} catch (ArithmeticException e) {
i = 30;
} catch (NullPointerException e) {
i = 40;
} catch (Exception e) {
i = 50;
}
}
}
上述代码通过:javap -v T14_ByteAnalyseMoreSingle_Catch.class进行反编译,得到如下字节码。
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=3, args_size=1
0: iconst_0
1: istore_1
2: bipush 10
4: istore_1
5: goto 26
8: astore_2
9: bipush 30
11: istore_1
12: goto 26
15: astore_2
16: bipush 40
18: istore_1
19: goto 26
22: astore_2
23: bipush 50
25: istore_1
26: return
Exception table:
from to target type
2 5 8 Class java/lang/ArithmeticException
2 5 15 Class java/lang/NullPointerException
2 5 22 Class java/lang/Exception
LineNumberTable: ...
LocalVariableTable: // 因为异常最终只会出现一种,这里采用了异常引用变量的槽位复用
Start Length Slot Name Signature
9 3 2 e Ljava/lang/ArithmeticException;
16 3 2 e Ljava/lang/NullPointerException;
23 3 2 e Ljava/lang/Exception;
0 27 0 args [Ljava/lang/String;
2 25 1 i I
StackMapTable: ...
上述说明:
因为异常出现时,只能进入 Exception table 中一个分支,所以局部变量表 slot 2 位置被共用。也算是一种优化,为节省栈帧内存的使用
1.3 异常-multicatch
先来看下异常-multi_catch代码示例:
// 从字节码角度来分析:multi-catch 的情况
// jdk1.7 新增multi catch
public class T15_ByteAnalyseMulti_Catch {
public static void main(String[] args) {
try {
Method test = T15_ByteAnalyseMulti_Catch.class.getMethod("test");
test.invoke(null);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
public static void test() {
System.out.println("ok");
}
}
上述代码通过:javap -v T15_ByteAnalyseMulti_Catch.class进行反编译,得到如下字节码。
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=2, args_size=1
0: ldc #2 // class com/jvm/t07_bytecode/T15_ByteAnalyseMulti_Catch
2: ldc #3 // String test
4: iconst_0
5: anewarray #4 // class java/lang/Class
8: invokevirtual #5 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
11: astore_1
12: aload_1
13: aconst_null
14: iconst_0
15: anewarray #6 // class java/lang/Object
18: invokevirtual #7 // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
21: pop
22: goto 30
25: astore_1
26: aload_1
27: invokevirtual #11 // e.printStackTrace:()V
30: return
Exception table:
from to target type
0 22 25 Class java/lang/NoSuchMethodException
0 22 25 Class java/lang/IllegalAccessException
0 22 25 Class java/lang/reflect/InvocationTargetException
LineNumberTable: ...
LocalVariableTable:
Start Length Slot Name Signature
12 10 1 test Ljava/lang/reflect/Method;
26 4 1 e Ljava/lang/ReflectiveOperationException;
0 31 0 args [Ljava/lang/String;
上述说明:
异常-multi_catch 字节码 对比 异常-多个catch字节码,并没有特别的地方,只是异常表Exception table 三个异常的 target都一致。也有 异常-多个catch字节码 异常对象引用在局部变量表中槽位复用。
文章最后,给大家推荐一些受欢迎的技术博客链接:
本文地址:https://blog.csdn.net/weixin_32265569/article/details/108024235
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!