• try-finally 字节码分析


    我们都知道下面的代码返回值为8,下面通过字节码看下是怎么返回8的.

    public int tryFinally(){
            int i = 0;
            try{
                i++;
                return i;
            }finally {
                i = 8;
                return i;
            }
        }

    通过javap -v  命令输出字节码

    public int tryFinally();
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=4, args_size=1
             0: iconst_0               //表示将常量0加载到操作数栈
             1: istore_1               //表示将栈顶数据存储到index为1的局部变量中, 我们姑且记做local1=0
             2: iinc          1, 1     //将index为1的局部变量的值做自增操作,local1=1
             5: iload_1                //将index为1的局部变量的值加载到操作数栈,即常量1入栈
             6: istore_2               //将栈顶数据存储到index为2的局部变量, local2=1
             7: bipush        8        //将常量8入栈
             9: istore_1               //将栈顶值8存储到index为1的局部变量, local1=8
            10: iload_1                //将index为1的局部变量的值加载到操作数栈,即8入栈
            11: ireturn                //正常返回(没有异常发生), 返回栈顶值8
            12: astore_3               //从下面的异常表,可以看出,如果2~7发生异常,那么从12开始执行.此时将栈顶值存储到局部变量3
            13: bipush        8        //常量值8入栈
            15: istore_1               //将常量值8存储到局部变量1,即local1=8
            16: iload_1                //局部变量1值加载到操作数栈,及常量8入栈
            17: ireturn                //返回栈顶值8
          Exception table:             //异常表
             from    to  target type
                 2     7    12   any   //表示如果2~7发生异常,那么从12开始执行
                12    13    12   any   //表示如果12~13发生异常,那么从12开始执行

    从字节码我们可以看出无论try语句是否出现异常,finally语句块都会执行,根据字节码我们可以看出,最终返回的值无论是否发生异常都是返回8

    加载指令

    load

    将一个局部变量加载到操作数栈的指令有:

      iload, iload_<n>,lload,lload_<n>,fload,fload_<n>,dload,dload_<n>,aload,aload_<n>

      其中load前面的i,l,f,d,a分别表示数值类型为i,long,float,double,引用类型.n表示在局部变量表中下标为n的局部变量

          iload_1表示将局部变量表中下标为1的局部变量的值加载到操作数栈

    常量入栈的jvm指令有:

      bipush, sipush, ldc, ldc_w, ldc2_2,aconst_null, iconst_m1,iconst_<i>,lconst_<l>,fconst_<f>,dconst_<d>

      iconst_m1 表示将常量-1入栈

      iconst_<i> 表示将常量0~5入栈,iconst_0 表示将常量0入栈

      bipush 表示将-128~127的整数入栈

      sipush 表示将-32768~32767的整数入栈

      lconst_<l>表示将long类型数常量入栈

      fconst_<l>表示将flost类型常量入栈

      dconst_<d>表示将double类型常量入栈

      ldc 表示将字符串或者数值类型常量入栈

    存储指令

    store

    将一个数值从操作数栈存储到局部变量表的指令有:

      istore、istore_<n>、lstore、lstore_<n>、fstore、fstore_<n>、dstore、dstore_<n>、astore、astore_<n>

      如istore_2 表示将操作数栈顶值存储到局部变量表中下标为2的类型为int的局部变量

  • 相关阅读:
    c# 调用C++动态库 问题
    Web应用简易框架。
    【转】SVN历史版本删除(为SVN库瘦身)
    程序员7武器序
    小系统单据自动生成存储过程
    【转】数据库和数据仓库的区别
    jQuery之extend 函数
    .NET单元测试断言(Assert)
    c#类型转换操作符:as和is
    oracle 表数据合并
  • 原文地址:https://www.cnblogs.com/tracer-dhy/p/6279786.html
Copyright © 2020-2023  润新知