从字节码的角度来看try-catch-finally和return的执行顺序
来源:互联网 发布:西门子plc编程视频 编辑:程序博客网 时间:2024/06/07 07:04
从字节码的角度来看try-catch-finally和return的执行顺序
全篇以一个例子来说明:
先看如下的例子代码:
public class ExceptionTest { public void testException(){ try{ inside_try(); } catch(Exception e){ inside_catch(e); } finally{ inside_finally(); } } //分别为try块、catch块和finally块中被调用的函数 public void inside_try(){ } public void inside_catch(Exception e){ } public void inside_finally(){}}
通过javap -c ExceptionTest
命令可以看到此类的字节码如下:
如果没有抛异常,那么它的执行顺序为:
0: aload_0 1: invokevirtual #2 // Method inside_try:()V 4: aload_0 5: invokevirtual #3 // Method inside_finally:()V 8: goto 31 31: return
即先执行try里面的代码块,然后执行finally里面的代码块。
如果try中抛了一个异常,那么JVM会在如下的异常表中寻找跳转位置。
Exception table: from to target type 0 4 11 Class java/lang/Exception 0 4 24 any 11 17 24 any
从异常表中,可以看到有三种异常情况发生导致执行的路径不同:
第一种:如果位于0到4字节之间的命令(即try块中的代码)抛出了Class java/lang/Exception
类型的异常,则跳转到第11个字节开始执行catch中的代码;
第二种:如果位于0到4字节之间的命令(即try块中的代码)抛出了任何类型的异常,则跳转到第24个字节开始执行finally里面的代码。
第三种:如果位于11到17字节之间的命令(即catch块中的代码)跑出了任何类型的异常,则跳转到第24个字节开始执行finally里面的代码。
先看第一种情况:如果位于0到4字节之间的命令(即try块中的代码)抛出了Class java/lang/Exception
类型的异常,则跳转到第11个字节开始执行catch中的代码
指令如下:
11: astore_1 12: aload_0 13: aload_1 14: invokevirtual #5 // Method inside_catch:(Ljava/lang/Exception;)V 17: aload_0 18: invokevirtual #3 // Method inside_finally:()V 21: goto 31 31: return
astore_1会把抛出的异常对象保存到local variable数组的第二个元素。剩余的几行指令用来调用catch和finally块中的方法。
再看第二种情况:如果位于0到4字节之间的命令(即try块中的代码)抛出了任何类型的异常,则跳转到第24个字节开始执行finally中的代码
指令如下:
24: astore_2 25: aload_0 26: invokevirtual #3 // Method inside_finally:()V 29: aload_2 30: athrow 31: return
astore_2会把抛出的异常对象保存到local variable数组的第二个元素。下面的两行指令用来调用finally块中的方法。
25: aload_026: invokevirtual #3 // Method inside_finally:()V
最后通过如下的指令抛出异常
29: aload_2 30: athrow
最后一种情况,如果位于11到17字节之间的命令(即catch块中的代码)跑出了任何类型的异常,则跳转到第24个字节开始执行finally里面的代码。
这种情况的代码与上面一样,直接执行finally块中的代码。
再来看下try和catch中有return语句的情形
例子代码如下,在catch块中有return语句:
public class ExceptionTest { public void testException(){ try{ inside_try(); } catch(Exception e){ inside_catch(e); return;//catch块中有return语句 } finally{ inside_finally(); } } //分别为try块、catch块和finally块中被调用的函数 public void inside_try(){ } public void inside_catch(Exception e){ } public void inside_finally(){}}
用javap -c ExceptionTest命令查看字节码如下:
从字节码可以看出,即使try块中发生了异常,catch块中的return语句也是在finally块后面执行。
- 从字节码的角度来看try-catch-finally和return的执行顺序
- try, catch, finally, return的执行顺序
- try、catch、finally、return的执行顺序
- try、catch、finally、return的执行顺序
- try catch finally return 的执行顺序
- try、catch、finally、return的执行顺序
- try catch finally return 的执行顺序
- try catch finally return 的执行顺序
- try-catch-finally-return的执行顺序
- try、catch、finally、return的执行顺序
- try catch finally return 的执行顺序
- try-catch-finally中finally的break,return执行顺序
- try,catch和finally的执行顺序
- 含有return 的try catch finally的执行顺序
- 含有return 的try catch finally的执行顺序
- 含有return 的try catch finally的执行顺序
- Java含有return 的try catch finally的执行顺序
- try-catch-finally的执行顺序(有return的情况)
- SwipeToDismiss实现左右滑动删除Listviewk
- arm-linux-androideabi-g++: error: CreateProcess: No such file or directory make.exe: *** [obj/local/
- 学习日志(2)
- iOS之UIButton无法显示文字
- Info.plist和pch文件的作用
- 从字节码的角度来看try-catch-finally和return的执行顺序
- 二叉排序树
- 数组基本操作(四)
- 我认为的学习方法10.0(9.0和《实践与理论的思考》的结合)
- 矩阵论:把线性变换用矩阵进行表示 的推导
- ubuntu-unity桌面禁用客人会话
- 常用正则表达式大全 (转)
- 高斯正态云模型
- HTTP返回请求数据的三种方式