从jvm层面搞懂java的i++

> 本博客将从java字节码的层面解剖为什么i=0;i=i++;仍然会等于0

image-20240705164601567

字节码解析:

  • iconst_x:代表将常量x放到操作数栈中image-20240705164741928
  • istore_x:其中x必须是局部变量表中的一个合法下标,然后我们会从操作数栈中弹出对应的栈尾的元素(需要是int)以之来进行设置image-20240705165042321
  • iload_x:则是加载对应的局部变量表的x下标到操作数栈中
  • innc x by y:意思大概就是直接给局部变量表中x下标increase yimage-20240705165243552

解释

运行后的结果会是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;也能正确分析出字节码

下面仅作为答案展示:

image-20240705170107147

跨度为1的自增哪种效率最高

结论:

i++=i+=1>i=i+1,该结论仅从生成字节码数量进行讨论,实际测试在下方

image-20240705170429619

实测部分

由于int难分胜负,所以我采用了long,long在实际中的字节码数量会多不少,但是也同样能体现出这三种方法的效率不同,恰恰相反

image-20240705171234817

image-20240705171304857

image-20240705171345180

posted @ 2024-07-05 17:19  海山了-  阅读(13)  评论(0编辑  收藏  举报