群聊看到一个有意思的问题:
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++;
原文:https://www.cnblogs.com/LintonW/p/14085260.html