觉得这题挺有趣的,所以还是可以写一篇文章来说说
public class Main {
public static void main(String[] args) {
int i = 0;
i = i++;
System.out.println(i);
}
}
这段代码的执行结果是什么呢?
大多数人都觉得是 1,确实以我们的理解,单从源码来看不管怎么理解都应该是1
所以这次我们看看jvm指令,看看到底是怎么一回事
这是反编译后的jvm指令,我们只要关注红框那一部门就行了,LINENUMBER 这个可以忽略,它表示第多少行
ICONST_0 //把0放入到操作数栈
ISTORE 1 //把栈顶的那个值放入到局部变量表的索引为1的那个位置中 此时就是 int i = 0; 这两个指令执行完后 i 就等于 0 了,有值了
ILOAD 1 把局部变量表中索引为1的值放到操作数栈顶
IINC 1 1 对局部变量表中索引为1的值进行 + 1 此时局部表量表中的 i = 1
ISTORE 1 把栈顶的值赋值给局部变量表中索引为1的位置,此时 i = 0
从上面分析看来,原来是栈顶的 0 把 1 给覆盖了,也就是类似于
int i = 0; //定义i = 0
int temp = i; //把i 放入到临时变量中
i = i + 1; //对i 进行 + 1
i = temp; //然后又覆盖掉了 i 的值
如果把代码改成
int i = 0;
i = ++i;
System.out.println(i);
此时i就是等于1了
看看什么发生了变化
先进行 + 1 然后再把 + 1后的值放入栈顶,之后再赋值给 i
类似于下面这段代码
int i = 0;
i = i + 1;
int temp = i;
i = temp;