今天和一位大佬同学聊天的时候,被问了一个问题:
int i =3;
i = i++;
i = i++;
System.out.println(i);
我一看就觉得好简单,不就是4吗。
结果他告诉我不对,答案是3。
那一瞬间,我仿佛觉得自己是不是在做梦!
经过我努力百度,终于知道了为啥是这样子。
首先将这段代码编译,
public class Ipp {
public static void main(String[] args) {
int i =3;
i = i++; //i的值是3
}
}
然后就可以用 javap 命令反编译出字节码
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: istore_1
2: iload_1
3: iinc 1, 1
6: istore_1
7: return
其中:
0: iconst_3 表示将3(int)入栈
1: istore_1 表示将栈顶int类型值保存到局部变量1(i)中
2: iload_1 表示将局部变量1(i)中int类型值入栈
3: iinc 1, 1 表示将整数值1加到1指定的int类型的局部变量(i)中
6: istore_1 表示将栈顶int类型值保存到局部变量1(i)中
同样的,为做对比,可以用同样的方法得出
public class Ipp {
public static void main(String[] args) {
int i =3;
i = ++i; //i的值是4
}
}
的字节码
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: istore_1
2: iinc 1, 1
5: iload_1
6: istore_1
7: return
不难看出,这里与上面的区别在于++i在自增之后会将i(4)的值入栈。
所以,上面i++的答案之所以是3而不是4是因为:虽然 在i++后i的值变成了4,但是此时值为4的i并没有被放入栈中(好吧,其实我目前不知道这是个啥栈),所以在将栈顶元素赋予i之后,i的值依旧是3。
所以,这个这个问题给我的教训就是要慎用自增,而且直接用 i++ 或者 ++i 就好,不要写 i = i++ 或者 i = ++i 这种让自己头疼,也让别人头疼的代码!
参考文章:https://www.cnblogs.com/longjee/p/8675771.html --Java字节码指令收集大全