从jvm层面搞懂java的i++
> 本博客将从java字节码的层面解剖为什么i=0;i=i++;仍然会等于0
字节码解析:
- iconst_x:代表将常量x放到操作数栈中
- istore_x:其中x必须是局部变量表中的一个合法下标,然后我们会从操作数栈中弹出对应的栈尾的元素(需要是int)以之来进行设置
- iload_x:则是加载对应的局部变量表的x下标到操作数栈中
- innc x by y:意思大概就是直接给局部变量表中x下标increase y
解释
运行后的结果会是0,是因为
i=i++;
=号的优先级比较低,所以i=解析出的istore_1会在innc之后,而i++的命令转换完是这样的
//因为i在前所以会先iload_1,效果是将对应的局部变量数组中对应的i的值放到操作数栈中(注意这里之所以有iload是因为i在等号右侧)
iload_1
//而之后++对应的是innc 1 by 1,他是直接对局部变量数组中对应的i进行增加的--->这点的验证可以把i=i++改成i++;即可证明
innc 1 by 1
//而最后i=对应的优先级最低,所以解析出的istore_1在最后,且istore的作用是取操作数栈中的栈尾元素,而栈尾可没有+1,所以回到0的情况
istore_1
由此相信你对于i=++i;也能正确分析出字节码
下面仅作为答案展示:
跨度为1的自增哪种效率最高
结论:
i++
=i+=1
>i=i+1
,该结论仅从生成字节码数量进行讨论,实际测试在下方
实测部分
由于int难分胜负,所以我采用了long,long在实际中的字节码数量会多不少,但是也同样能体现出这三种方法的效率不同,恰恰相反