java关键字finally底层原理

前言

        适合人群:具有一定jvm字节码基础,能看得懂字节码与理解异常表最好

我一般喜欢从宏观到微观,学习都是由宏入微,不会在微观做过多文章,但是会告诉大家是怎么去得到这些结论的,如何进入到微观世界。

情景

        先看以下这个最普通不过的try-catch-finally结构

    try {
             代码块A;
             return x;
        }catch (Exception e){
            代码块B;
            return x;
        }finally {
            代码块D;
        }

        对于程序员而言,finnally代码块D的执行非常显然,当然是无论上面是正常抑或是异常,最终都会执行代码块D;但是对于JVM又如何去保证我们所感受的这样呢?

原理

         其实一张图一蔽之:

        从上图来看,哪怕不知道异常表是什么,不知道多出来的C为何物,也能一眼看出,大概的意思就是,把代码块D插入到A和return之间,B和return之间,意思就是类似于这样:

    try {
             代码块A;
             代码块D;
             return x;
        }catch (Exception e){
            代码块B;
            代码块D;
            return x;
        }

        注意,这里只是说”类似“,因为实际情况代码块D还插入到另一个代码块C与throw之间,至于C是什么东西,就是编译器会生成一段当发生没有捕捉的异常的时候的代码块C,也就是说发生了catch不到的异常就会去执行C

        其实说到这里就够了,但是小伙伴又如何自己看到真相呢?想知道的那就往下继续看吧,不过可能需要一点基础知识

证明

        工具:用IDEA的插件搜索bytecode,安装bytecode或者bytecode with jclasslib,然后重启IDEA在左上角的tab栏目里的view->show bytecode/bytecode with jclasslib,就可以看字节码了。

        先写一段代码:

public static int test1() {
        int i = 1;
        try {
            return i;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }finally {
            System.out.println("good job");
        }
    }

        我们来看看它的字节码:

 

        

       至于看字节码好像执行顺序是A-D-B-D-C-D有木有?那么发生异常的时候又是如何跳转的呢?其实这是JVM的基础,在栈帧里有异常表,记录着异常发生时的跳转情况:

        然后再回过头看最开始的那张图(顶上一张异常表,下面是ABCD代码块的),是不是搞清楚finally的底层原理呢?

 最后

        希望大家能看懂,如果没看懂的话,那就再列举一下所需具备的工具与知识:1.jclasslib bycode插件 2.简单阅读字节码的能力 3.理解异常表的作用 4.简单区分前端编译器与jvm的作用

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值