【详细清晰】:局部变量表;操作数栈;i = i++;i = ++i 分析

1、知识补充

 JVM虚拟机里面有很多结构,本题主要用到局部变量表和操作数栈。

 局部变量表

       局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序被编译成Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的最大局部变量表的容量。

       局部变量表的容量以变量槽(Slot)为最小单位,32位虚拟机中一个Slot可以存放一个32位以内的数据类型(boolean、byte、char、short、int、float、reference和returnAddress八种)。

 操作数栈

       Java虚拟机的解释执行引擎被称为"基于栈的执行引擎",其中所指的栈就是指-操作数栈。操作数栈也常被称为操作栈。

       和局部变量区一样,操作数栈也是被组织成一个以字长为单位的数组。 它不是通过索引来访问,而是通过标准的栈操作—压栈和出栈—来访问的。

       虚拟机在操作数栈中存储数据的方式和在局部变量区中是一样的:如int、long、float、double、reference和returnType的存储。对于byte、short以及char类型的值在压入到操作数栈之前,也会被转换为int。

        虚拟机把操作数栈作为它的工作区——大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。

相关JVM字节码指令:

begin  
iload_0    // 将局部变量中索引为0的数据压入到操作数栈中
iload_1    // 将局部变量中索引为1的数据压入到操作数栈中
iadd       // 从操作数栈中弹出两个数据进行相加,然后将计算的结果压入栈中
istore_2   // 把操作数栈计算的结果存储到局部变量区索引为2的位置。
end  

2、程序分析

 (1) 代码 i  = i++ 分析:

    ① 等号“=”赋值的时候,先计算等号右边的,再将等号右边的结果赋值给左边。

   int i = 1;此时将 i 存储到局部变量表。

    因为是 i 要参与计算的,要把操作数压到操作数栈里面进行运算。

   

   ③ 此时,i++自增,自增导致i从1变成了2,将局部变量表中1变成2。

 ④ 此时,计算完了,还没有赋值, i = i++,将操作数栈的的1赋值给局部变量表中的2,覆盖。

 ⑤ 小结:i = i++ 执行的结果是1。

(2) 代码 int j  = i++ 分析:

  ① 还是先将 i 值压入栈中

② 然后 i 自增,在局部变量表进行自增,变成2

③ 然后将操作数栈中的1赋值给j

④ 小结:最终j的结果是1

(3) 代码 int k = i + ++i * i++ 分析:

① 先将 i 的值压入栈中

注意:int k = i +  ++i * i++;压入栈的过程是从 i 开始的,按照顺序进行。

② 然后是++i,i前自增后,局部变量表中的 i 变成3,并压入栈中。

③ 然后计算i++,先将操作数压入操作栈中,然后i在局部变量表中自增1

④ 然后再操作数中计算结果,每一步计算的结果压入栈中。最终结果赋值给局部变量表中的K

⑤ 小结,最终的结果是k = 11;i = 4;j = 1;

小结

JVM中class字节码指令如下:

iconst_1:定义常量1

istore_1[i];对第一个变量i赋值

iload_1[i]:将i压入操作数栈中

iinc_1 1[i]:局部变量表i自增1

istore_2 [j]:将第二个参数j压入栈中

imul:执行乘法

iadd:执行加法

istore_3 [k]:将第三个参数j压入栈中,执行结果返回

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值