从字节码层面理解i++和++i

4 篇文章 0 订阅

从字节码层面理解i++和++i

起因

无非就是网上常见的面试题

 public static void main(String[] args) {
        int i = 0;
        int result = i++ + ++i + i++;
        System.out.println(i);
        System.out.println(result);

    }

这种题目怎么理解才对呢?

我以前只知道,i=i++;i=++i;理解的话,通过背口诀,先赋值还是先+1. 但是上述面试题就不知道如何理解了。

当然面试题只是面试题,要是实际开发中有人这么写,头给他打爆。

理解

最近几天在看jvm,这个从编译出来的字节码就能很清晰的看出来为什么。

j=++i 从字节码来看,大概顺序是,innc 1 by 1 ;iload 1;istore_2

j=i++ 从字节码来看,大概顺序是,iload 1;innc 1 by 1 ;istore 2

i=++i 从字节码来看,大概顺序是,innc 1 by 1;iload 1;istore_1;

i=i++ 从字节码来看,大概顺序是,iload 1;innc 1 by 1;istore 1;

这里没有jvm知识的人,可能不太理解,其实jvm中,字节码运行通过俩个地方来不断交换数据来进行运行的。

在jvm中,局部变量表和操作数栈是两个不同的存储数据的内存区域。

innc 1 by 1 意思就是局部变量表数+1;

iload 1 意思是局部变量表1位置节点的数,加载到操作数栈。

istore 1 意思是从局部变量表出栈一个元素,覆盖到局部变量表1位置。

那么我们来理解一下j=++i;

innc 1 by 1 ;iload 1;istore_2

假设i=1;则

局部变量表1位置的数据1加1,则此时局部变量表1的数据为2。

获取局部变量表的1位置数据2,加载到操作数栈,则此时局部变量表1的数据为2,操作数栈数据为2.

操作数栈的数据2出栈,覆盖到局部变量表2的位置上。

那么此时局部变量表1既是i的数据为2,局部变量表2既是j的数据也是2。

同理

j=i++的话。

iload 1;innc 1 by 1 ;istore 2

假设i=1;则

获取局部变量表的1位置数据1,加载到操作数栈,则此时局部变量表1的数据为1,操作数栈数据为1.

局部变量表1位置的数据1加1,则此时局部变量表1的数据为2。

操作数栈的数据1出栈,覆盖到局部变量表2的位置上。

那么此时局部变量表1既是i的数据为2,局部变量表2既是j的数据也是1。

那i=++i的话。

innc 1 by 1;iload 1;istore_1;

假设i=1;则

局部变量表1位置的数据1加1,则此时局部变量表1的数据为2。

获取局部变量表的1位置数据2,加载到操作数栈,则此时局部变量表1的数据为2,操作数栈数据为2.

操作数栈的数据2出栈,覆盖到局部变量表1的位置上。

那么此时局部变量表1既是i的数据为2

那i=i++的话。

iload 1;innc 1 by 1;istore 1;

假设i=1;则

获取局部变量表的1位置数据1,加载到操作数栈,则此时局部变量表1的数据为1,操作数栈数据为1.

局部变量表1位置的数据1加1,则此时局部变量表1的数据为2。

操作数栈的数据1出栈,覆盖到局部变量表1的位置上。

那么此时局部变量表1既是i的数据为1

这几种情况理解后,自然就能清楚的理解上面的面试题,

i=3,result是4

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值