Java中为什么finally语句块一定会被执行?
来源:互联网 发布:墨脱公路沥青路面数据 编辑:程序博客网 时间:2024/05/16 19:22
通过阅读JVM规范,得知编译器是通过冗余来实现finally语句块的。我们可以写段代码做一个验证。
JDK版本:8
如下面的代码:
import java.io.*;public class Main { public static void main(String[] args) { try { foo(); } catch (IOException e) { int a = 100; } catch (Exception e) { int b = 200; } finally { int c = 300; } } public static void foo() throws IOException { }}
根据finally的语义,我们可以确定int c = 300
这行代码一定会被执行。我们可以用javap -v Main
来看看这段代码对应的字节码:
Code: stack=1, locals=5, args_size=1 0: invokestatic #2 // Method foo:()V 3: sipush 300 6: istore_1 7: goto 41 10: astore_1 11: bipush 100 13: istore_2 14: sipush 300 17: istore_1 18: goto 41 21: astore_1 22: sipush 200 25: istore_2 26: sipush 300 29: istore_1 30: goto 41 33: astore_3 34: sipush 300 37: istore 4 39: aload_3 40: athrow 41: return
其中,偏移量为14、17, 26、29, 和34、37的字节码就是int c = 300
对应的字节码。sipush 300
意为将300压入操作数栈,astore_N
意为将操作数栈顶元素保存到本地变量表中的第N个slot中。
由此我们可以清楚地看出,编译器确实是在每个catch
语句块后都添加了finally
块中的字节码, try
块的最后也有int c = 300
字节码的冗余。如果翻译成Java代码应该这样的:
public static void main(String[] args) { try { foo(); int c = 300; // 冗余 } catch (IOException e) { int a = 100; int c = 300; // 冗余 } catch (Exception e) { int b = 200; int c = 300; // 冗余 } finally { int c = 300; } }
由此可知,我们在写代码时,如果finally块中的代码过多会导致字节码条数”膨胀”,因为finally中的字节码会被”复制”到try块和所有的catch块中。
0 0
- Java中为什么finally语句块一定会被执行?
- java中finally语句是否一定会被执行
- java的try-catch-finally块中,finally中的代码是否一定会执行?
- java中finally一定会执行吗?
- Java牛角尖【013】: finally块中的代码一定会执行吗?
- finally代码块一定会执行吗?
- finally块中的代码什么时候被执行?finally是不是一定会被执行?(见最后引申)
- Java中finally语句块的深度解析(try catch finally的执行顺序)
- java Finally块中代码什么时候执行
- java中finally语句块注意事项
- 深度探究Java 中 finally 语句块
- 转:finally块中的代码一定会执行…
- Finally语句块的执行
- java中try中return语句与finally块执行顺序问题
- finally一定会执行吗?
- java try finally return 顺序,finally一定会执行吗?
- try中return语句与finally块的执行先后
- java try语句块 finally和return 的执行顺序
- Apriori算法及C++实现
- 最小生成树伪代码模板
- python常用函数
- Android Application对象必须掌握的七点
- Setup Python 开发环境和IPython的基本使用
- Java中为什么finally语句块一定会被执行?
- hdoj 2111 Saving HDU 【贪心】
- 解决U盘1KB快捷方式病毒(暴风一号)方法
- servlet路径问题
- Unity优化大全(十)之 Memory - Mono的托管内存
- Android平台HTTP断点续传的实现
- c++字符串学习
- php去除字符串中指定字符
- PHP:const和define的区别