i = ++i + i++ + i++ + i++原理

int i=0;

i = ++i + i++ + i++ + i++

一、从java定义的语法层面分析

++i 语义为先自增再赋值,所有此时的 i 为相加后的值

i++ 语义为先读取再自增,所以此时的 i 为相加前的值

根据这两个语义进行操作如下:

因为每一个自增操作的变量 i 都是前一个累加过的值,而最后的i++ 此时的自增的值没有后续操作去取,因此自增后的值不会参与计算,所以最后i=1+1+2+3最终结果为7.

二,从编译的字节码分析

i = ++i + i++ + i++ + i++

分析前先把相关的字节码指令解释下: 

iconst_0把int类型的常量0加载到栈帧的操作数栈中

istore_1把操作数栈栈顶中int类型的变量值存储到栈帧的局部变量表索引为1的位置。

iinc 1, 1 这个函数有些特殊,它直接把局部变量表的值加1,第一个1是指向局部变量表中索引的位置,第二个1表示给找到的值                 加1。

iload_1 把局部变量表中的索引为1的值加载到操作数栈栈顶。

iadd      把栈顶int类型的两个数相加

介绍完,看生成的字节码如下:

 Code:
       0: iconst_0 //加载int类型的常量值为0,到操作数栈栈顶也就是定义的 int i=0
       1: istore_1//吧栈顶的数据存储到局部变量表索引为1的位置
       2: iinc          1, 1 //把局部变量表索引为1的值自增1,此时局部变量表中的i=0,加1后等于1
       5: iload_1  //把局部变量表索引为1的值加载到操作数栈 栈顶   也就是把1复制到栈顶
       6: iload_1//再次把局部变量表索引为1的值加载到操作数栈 栈顶 也就是把1复制到栈顶
       7: iinc          1, 1  //此时把局部变量表中索引为1的数加1,也就是把1+1=2,此时的局部变量表中的数为2
      10: iadd    //把栈顶的两个数相加,此时栈顶的数时两个1,在5和6两步加载的,所以此时相加等于1+1=2,放到栈顶
      11: iload_1//把局部变量表下标为1的数值加载到栈顶,此时局部变量表中的值为2.
      12: iinc          1, 1//再次把局部变量表中的下标为1的数值加1,也就是2+1=3
      15: iadd        //把操作数栈中的两个数据相加,此时栈顶数据为10和11两个操作也就是2+2=4,放到栈顶
      16: iload_1  //把局部变量表中下标为1的数值复制到栈顶,此时局部变量表中的数据为3,在12步的时候操作的
      17: iinc          1, 1//把局部变量表中的数据加1,也就是3+1=4
      20: iadd  //把栈顶的两个数据相加,此时栈顶的数据为15和16步时放的值,4+3=7,放到栈顶
      21: istore_1//把栈顶数据存储到局部变量索引为1的位置,保存后,此时局部变量表中的数值为7
      22: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      25: iload_1         //把局部变量表中下标为1的数据加载到栈顶,此时值为7
      26: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V 调用函数,打印出栈顶数据为7
      29: return

此时会有疑问,我们在分析自增表达式时,不知道虚拟机生成字节码的顺序,所以就不会知道生成的结果,因此咱们对照着生成的字节码,来分析:

++i + i++ + i++ + i++

当java遇到++i的时候会先执行iinc再执行iload

当java遇到i++的时候会先执行iload然后再执行iinc

因此++i + i++ + i++ + i++的顺序为:

1、iinc   //++

2、iload //i

3、iload //i

4、iinc  //++

5、iadd //+  此处的+为两个变量的相加不是自增的+

6、iload//i

7、iinc//++

8、iadd/+ 此处的+为两个变量的相加不是自增的+

9、iload/i

10、iinc//++

11、iadd//+  此处的+为两个变量的相加不是自增的+

对比发现,这个顺序跟jvm生成的字节码顺序一致,因此,我们完全可以通过这样的分析来判断这种自增相加问题的结果。

如有疑问欢迎留言,共同讨论,一起进步

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值