page contents

i++与++i的水有多深,你真的了解吗?

i++是先算后加,++i是先加后算,这个在我们学习循环就已经知道的东西,到底蕴含了什么呢? 我们来看一段代码: int i1=10;int i2=i1++;​int i3=10;int i4=++i3;​int i5 = 10;i5 = i5++;​int i...

i++是先算后加,++i是先加后算,这个在我们学习循环就已经知道的东西,到底蕴含了什么呢?

我们来看一段代码:

int i1=10;int i2=i1++;int i3=10;int i4=++i3;int i5 = 10;i5 = i5++;int i6=10;i6 = ++i6;int i7=10;int i8 = i7++ + ++i7;i7=10;int i9 = ++i7 + i7++;

稍稍有点眼花缭乱,没关系,很简单,认真看看就能看懂,那么他们输出什么呢?

i1=:11i2=:10i3=:11i4=:11    //直到i4大家都应该懂i5=:10    // i5以后可能有点难度i6=:11i7=:12i8=:22i9=:22

要解释i5,i6,i8,i9,需要从java的字节码角度去探索。

>> 栈结构

我们知道,java虚拟机中对象一般在堆中,而常量运算一般在栈中(这里是简略描述,真实比这个复杂)。

上面的所有运算都是在栈中完成的,栈的基本单位是栈帧,而一个方法所占用的空间就是一个栈帧,上面只有一个main方法,所以占用一个栈帧。

640?wx_fmt=png

每个栈帧对应一个方法,包含五个内容,但是由于我们这道题只涉及局部变量表和操作数栈,我们只看这两个:

640?wx_fmt=png

>> 字节码

现在我们知道,我们的代码将会在栈帧中的局部变量表和操作数栈中发生事情,那如何发生?,就是通过字节码指令运行,字节码由java代码编译而来,在idea中安装jclasslib插件即可查看。

先了解以下4行代码:

0 bipush 10   //将10压入操作数栈2 istore_1    //将栈顶的数保存到局部变量表的1位置处3 iload_1    //将局部变量表1位置处的值取出4 iinc 1 by 1 //将局部变量表中1位置处的值自增1

好,准备工作做完了,现在开始分析。

前6个:

int i1=10;int i2=i1++;int i3=10;int i4=++i3;int i5 = 10;i5 = i5++;int i6=10;i6 = ++i6;

字节码如下,字节码前面的数字表示的是地址,不是代码行数。

0 bipush 10      //压入10到栈中2 istore_1      //将栈顶的10保存到局部变量表的1处(简称i1)3 iload_1        // 复制i1并取出4 iinc 1 by 1    //自增位于局部变量表中的i1  7 istore_2       //将取出的i1放到局部变量表的2处(简称i2)//注意,这里是先取出再自增,取出的i1还是原值,所以i2依旧为108 bipush 1010 istore_311 iinc 3 by 1     //这里是先自增再取出14 iload_315 istore 4        //i4为1017 bipush 1019 istore 5        21 iload 5         //i5先取出23 iinc 5 by 1     //局部变量表处再自增26 istore 5        //又将取出的值存回去,所以先取出的10覆盖了自增的1128 bipush 1030 istore 632 iinc 6 by 1    //i6先自增再取出35 iload 637 istore 6       // 所以取出的是11,覆盖的也是11

最后两个:

int i7=10;int i8 = i7++ + ++i7;i7=10;int i9 = ++i7 + i7++;

首先我们明确,自增操作符++的优先级高于运算符+号,而且是从左到右运算。

来看字节码:

 39 bipush 10 41 istore 7 43 iload 7 45 iinc 7 by 1 48 iinc 7 by 1 51 iload 7 53 iadd 54 istore 8 56 iinc 7 by 1 59 iload 7 61 iload 7 63 iinc 7 by 1 66 iadd 67 istore 9

这就是i7++与++i7的字节码混合,如图

640?wx_fmt=png

i7++中局部变量表处自增时,由于没有执行=号,所以没有存回去,这个时候,轮到了++i7,++i7执行了自增后,实际上局部变量表中的i7此时已经是12了。

所以23行 iload 7的值为10,但是26行iload 7的值为12,综合下来,还是22。

至于i9,一样的道理,可以自己探索哦~

  • 发表于 2020-02-05 11:21
  • 阅读 ( 623 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章