Java字节码角度分析异常处理
程序员文章站
2022-04-06 22:39:18
在前面的文章中,有详细地介绍java字节码相关的知识,有兴趣的可以提前了解一下。1.Java字节码的一段旅行经历——提升硬实力12.Java字节码角度分析a++ ——提升硬实力23.Java字节码角度分析条件判断指令 ——提升硬实力34.Java字节码角度分析循环控制 ——提升硬实力45.Java字节码角度分析判断结果 ——提升硬实力56.Java字节码角度分析构造方法 ——提升硬实力67.Java字节码角度分析方法调用 ——提升硬实力78.Java字节码角度分析多态原理 —...
目录
从字节码角度来分析:异常处理
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字节码 异常对象引用在局部变量表中槽位复用。
文章最后,给大家推荐一些受欢迎的技术博客链接:
- Hadoop相关技术博客链接
- Spark 核心技术链接
- JAVA相关的深度技术博客链接
- 超全干货--Flink思维导图,花了3周左右编写、校对
- 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
- 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
- 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂
本文地址:https://blog.csdn.net/weixin_32265569/article/details/108024235
上一篇: MAC 命令行启动tomcat的详细介绍