之前实习背八股文的时候,有刷到过这样一道题目
int count = 0;
for (int i = 0; i < 100; i ++) {
count = count ++;
}
System.out.println(count);
问程序输出多少,当时看到答案输出是0的时候,整个人都是蒙圈的,怀疑了整个世界。后来也去查阅了不少资料,统一给出的答案都是,count在自增后会被原来的值覆盖,所以无论怎么循环都还是原来的数字,对于当时比较菜鸡的我来说,看jvm的字节码指令无疑是看天书一样,直到最近在读jvm相关的书籍的时候,又想到了这个问题,所以牵出来溜溜。
先看下面两段的程序及反编译后的字节码指令
int i = 0;
i = i++;
int i = 0;
i = ++i;
要理解为啥结果不一样,其实理解了这几个命令就不难了。这里就不一一介绍了,挑重点的说吧
iload是吧局部变量表里的变量压入到操作数栈(jvm都是在操作数栈里执行操作,然后再写入到局部变量表的),iinc是做递增操作。就第一段程序而言,我的理解是这个指令是直接在局部变量表里执行的,所有操作数栈没有变化,还是原来的值,随后又将旧值写入(istore_1)到局部变量表,覆盖了递增后的值。而第二段则是先做的递增,然后将递增后的值压入到操作数栈再写回局部变量表,所以达到了递增的操作。