前言
==
- 不管是学习C 的时候还是学习java的时候我们都被老师灌溉了
i
和i
的不同 - 前者是先赋值在进行 1操作而后者是先进行 1在进行赋值 。 我们也肯定在程序中因为两者的使用不当导致我们程序计算错误
问题描述
====
- 问题是这样的!本着先加后加的原则就开始盲目的背诵记忆了。一直认为
i
和i
他们执行就是不同的。但是看了字节码才发现 - 具体的场景我们这里也不需要进行具体说明了。
问题分析
====
- 我们直接就对
i
、i
进行分析。对于两者区别我们不用赘述。今天我们从字节码层面来看看两者执行的区别 - 对!我们就是要抛开外壳看本质东西
- 这段代码应该很简单明了了。我们通过编译查看下他的字节码吧。编译字节码方式很多你可以直接通过
javac
。 我这里通过idea的插件来生成了。有细微的差别但是不会影响我们阅读的 。 为了阅读方便我截取了main主函数部分的字节码 - 为了方便理解我们先理解下里面的指令含义吧
指令
含义
ICONST_x
将至x压到操作数栈中
ISTORE_x
将操作数栈顶元素写入到本地变量表第x 1位置
IINC m n
将本地变量表中第m 1位置进行加n操作
LINENUMBER
这个就是标注我们的行号
ILOAD_x
将本地变量表第x 1位置元素加入操作数栈中 和ISTORE相反
- 有了这五个指令的理解我们在阅读下i 的字节码吧。
- ①、首先将值为3压入操作数栈中
- ②、然后将操作数栈顶中元素写入到本地变量表第二个位置
- ③、将本地变量表第二个位置内容加1操作
- ④、结束
- ⑤、为什么是加入到本地变量表第二个位置。因为本地变量表第一个默认是args 。就是主程序
- 当我看了
i
的字节码后发现跟i
执行一模一样 。 最终在本地变量表中的i都是2 。 所以说理解还是得看底层
习以为常的区别
=======
- 上面我们通过字节码层面展示
i
和i
他们两个是没有区别的。那么我们平时认为的区别是什么情况呢 - 对~ 。 我们得和赋值结合起来看才能看出中间的端倪
- 上面是两段代码和两段代码对应的字节码。内部的却别就是与i 是先ILOAD再IINC . i是先IINC在ILOAD。最终导致本地变量表的i在两段程序中结果不一样
总结
==
- 有时候从别人那学到的总结经验仅仅是经验,并不一定能够说明内部深层次的东西。
- i 先赋值后加1 。 i先加1后赋值 很多人肯定认为两个字节码执行不同。实际上呢。还是得看底层东西
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!