群聊看到一个有意思的问题:

i=1;

i+=(++i)+(i++);

输出:

i=5

然后结果 i=5 怎么得出来的呢?

通过反编译获取字节码,得到主要代码如下:

public static void main(java.lang.String[]);
    Code:
        0:iconst_1        // 直接取常量(整数 1),压入栈中
        1:istore_1        // 弹栈,并存入局部变量(Slot 0)
        2:iload_1         // 从局部变量(Slot 0)取值,压入栈中
        3:iinc        1,1    // 对局部变量(Slot 0)进行自增(+1)操作,与栈无关
        6:iload_1
        7:iload_1
        8:iinc        1,1
       11:iadd
       12:iadd
       13:istore_1
       14:getstatic 
       17:iload_1
       18:invokevirtual
       21:return
}

通过字节码可以得知,首先执行 i=1,将常量放入栈中,然后弹栈,将常量存入局部变量slot 0中,又将局部变量slot 0中值压入栈中,此时,栈中只有一个值 1。

接下来对局部变量slot 0中的常量1进行自增,slot 0中值变为2;执行iload_1 ,对局部变量slot 0取值并压入栈中,然后又执行了一次iload_1,此时栈中存有 1,2,2三个值。

再一次执行iinc的时候,只是对局部变量slot 0中值进行了操作,局部变量slot 0 中的值 2+1=3,但这个值并没有压入栈中。

接下来执行了两次iadd,分别对栈中最接近栈顶的两个值进行了求和,并存入栈中。

2+2=4
4+1=5

所以最终得出结果为5.

观察原表达式,

i+=(++i)+(i++);
//实际等价于执行
a = i;
i++;
b = a+i+i;
i++;

 


 

posted on 2020-12-04 13:06  LintonW  阅读(458)  评论(0)    收藏  举报