i++和++i并没有区别,字节码告诉你 | Java Debug 笔记

240 阅读3分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>

前言

  • 不管是学习C++的时候还是学习java的时候我们都被老师灌溉了i++++i的不同
  • 前者是先赋值在进行+1操作而后者是先进行+1在进行赋值 。 我们也肯定在程序中因为两者的使用不当导致我们程序计算错误

问题描述

  • 问题是这样的!本着先加后加的原则就开始盲目的背诵记忆了。一直认为i++++i他们执行就是不同的。但是看了字节码才发现
  • 具体的场景我们这里也不需要进行具体说明了。

问题分析

  • 我们直接就对i++++i 进行分析。对于两者区别我们不用赘述。今天我们从字节码层面来看看两者执行的区别
  • 对!我们就是要抛开外壳看本质东西

image-20210514132208664

  • 这段代码应该很简单明了了。我们通过编译查看下他的字节码吧。编译字节码方式很多你可以直接通过javac 。 我这里通过idea的插件来生成了。有细微的差别但是不会影响我们阅读的 。 为了阅读方便我截取了main主函数部分的字节码

image-20210514132406577

  • 为了方便理解我们先理解下里面的指令含义吧
指令含义
ICONST_x将至x压到操作数栈中
ISTORE_x将操作数栈顶元素写入到本地变量表第x+1位置
IINC m n将本地变量表中第m+1位置进行加n操作
LINENUMBER这个就是标注我们的行号
ILOAD_x将本地变量表第x+1位置元素加入操作数栈中 和ISTORE相反
  • 有了这五个指令的理解我们在阅读下i++的字节码吧。
  • ①、首先将值为3压入操作数栈中
  • ②、然后将操作数栈顶中元素写入到本地变量表第二个位置
  • ③、将本地变量表第二个位置内容加1操作
  • ④、结束
  • ⑤、为什么是加入到本地变量表第二个位置。因为本地变量表第一个默认是args 。就是主程序

image-20210514134128268

  • 当我看了++i的字节码后发现跟i++执行一模一样 。 最终在本地变量表中的i都是2 。 所以说理解还是得看底层

习以为常的区别

  • 上面我们通过字节码层面展示i++++i他们两个是没有区别的。那么我们平时认为的区别是什么情况呢
  • 对~ 。 我们得和赋值结合起来看才能看出中间的端倪

image-20210514135136083

  • 上面是两段代码和两段代码对应的字节码。内部的却别就是与i++是先ILOAD再IINC .++i是先IINC在ILOAD。最终导致本地变量表的i在两段程序中结果不一样

总结

  • 有时候从别人那学到的总结经验仅仅是经验,并不一定能够说明内部深层次的东西。
  • i++先赋值后加1 。 ++i先加1后赋值 很多人肯定认为两个字节码执行不同。实际上呢。还是得看底层东西

点赞