从字节码角度理解JVM异常处理机制的原理
来源:互联网 发布:济南婚纱摄影 知乎 编辑:程序博客网 时间:2024/06/08 05:52
前几天看到一条阿里巴巴的面试题:你了解try-catch块的实现原理吗?
我服,阿里的面试题就是有深度啊。要答好这一题,我觉得需要反编译一下.java源文件,因为字节码面前了无秘密。
反编译一段小程序
为了简单起见,我搞了一段没什么实际意义的try-catch示例代码。
public class Main { public static void main(String[] args) { int a = 1; int b = 3; try { b = a + b; return; } catch (RuntimeException e1) { b = a - b; } catch (Exception e2) { b = a * b; } finally { a = 0; } }}
通过命令javap -c Main 反编译.class文件得到一下输出:
public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 // 给局部变量表1号slot赋值为1,代表a 2: iconst_3 3: istore_2 // 给局部变量表2号slot赋值为3,代表b 4: iload_1 // try块开始! 5: iload_2 6: iadd 7: istore_2 // 指令4-7 完成了操作:b = a + b 8: iconst_0 // finally块开始! 9: istore_1 // 指令8-9 完成操作a=0 10: return // 函数执行完毕,返回 11: astore_3 // RuntimeException e1异常处理块开始! 12: iload_1 13: iload_2 14: isub 15: istore_2 16: iconst_0 // finally处理块 17: istore_1 18: goto 38 // RuntimeException e1异常处理块结束! 21: astore_3 // Exception e2异常处理块开始! 22: iload_1 23: iload_2 24: imul 25: istore_2 26: iconst_0 // finally处理块 27: istore_1 28: goto 38 // Exception e2 异常处理块结束! 31: astore 4 // 其他任何异常处理块 33: iconst_0 34: istore_1 35: aload 4 37: athrow // 往将异常外抛 38: return Exception table: // 异常表 from to target type 4 8 11 Class java/lang/RuntimeException //4-8 号指令中,碰到 NullPointerException时,跳到 11 号指令 4 8 21 Class java/lang/Exception 4 8 31 any 11 16 31 any 21 26 31 any 31 33 31 any}
以上指令的注释是我加上去的,请大家对照源码加以理解。
总结
如果大家看完之后仍然有点模糊,相信看了下图后会对try-catch代码对应的字节码指令结构有一个全面的理解。
try块的范围就是体现在异常表行记录的起点和终点。JVM 在 try 住的代码区间内如有异常抛出的话,就会在当前栈桢的异常表中,找到匹配类型的异常记录的入口指令号,然后跳到该指令处执行。异常指令块执行完后,再回来继续执行后面的代码。JVM 按照每个入口在表中出现的顺序进行检索,如果没有发现匹配的项,JVM 将当前栈帧从栈中弹出,再次抛出同样的异常。当 JVM 弹出当前栈帧时,JVM 马上终止当前方法的执行,并且返回到调用本方法的方法中,但是并非继续正常执行该方法,而是在该方法中抛出同样的异常,这就使得 JVM 在该方法中再次执行同样的搜寻异常表的操作。
参考:JVM 对 Java 异常的处理原理
0 0
- 从字节码角度理解JVM异常处理机制的原理
- 从源码的角度理解Android消息处理机制
- 从jdk源码角度理解jvm类加载机制
- 从JVM角度理解线程
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- 【转】Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- 【 Android】handler异步消息处理机制完全解析,带你从源码的角度彻底理解
- Android异步消息处理机制完全解析,带你从源码的角度彻底理解
- 生成sqlite3.lib
- 创建Git新分支步骤
- FFMPEG x264编译
- poj3352——Road Construction(双连通分量)
- HDOJ 2098 分拆素数和
- 从字节码角度理解JVM异常处理机制的原理
- 小程序猿的第一篇博客
- Androidstudio 转换大小写快捷键
- hdu 1392(凸包周长)
- Android RecyclerView 使用
- KMP废柴のKMP小练
- poj3177——Redundant Paths(双连通分量)
- IAR软件调试延时时间
- etcd集群搭建步骤