一篇文章带你从java字节码层理解i++和++i
目录
- 程序目的
- 关键指令
- i++示例源码
- 使用jclasslib查看i++字节码
- ++i示例源码
- 参考
- 总结
程序目的 从java字节码层理解,为何i = i++后,结果是+1之前的数值。而i=++i后,结果是+1之后的值。
关键指令
iload_:
从局部变量表获取值,并压入操作数栈。istore_:
出栈,然后存储到局部变量表。i++示例源码
public class TestIPulsPlus { public static void main(String[] args) {int i = 8; i = i++; //i = ++i; System.out.println(i); }}
i++执行结果:
8
使用jclasslib查看i++字节码 找到main方法的Code区:
文章图片
图:i=i++字节码
字节码解读
0 bipush 8
把数值8压入操作数栈,压栈前转为int类型。
2 istore_1
8出栈,存到编号为1的局部变量表。
文章图片
图:编号为1的局部变量为1
以上两行指令,完成了
int i = 8;
这行代码。3 iload_1接下来,解读i=++i的字节码
从局部变量表,获取int值8。然后压到操作数栈。
4 iinc 1 by 1
把局部变量表中的i,进行+1操作。此时栈里面数值是8,局部变量表中i为9。
7 istore_1
8出栈,存到编号为1的局部变量表。也就是赋值给i变量。局部变量表的i值从9变为8。
文章图片
图:i=++i; 字节码
++i示例源码
public class TestIPulsPlus { public static void main(String[] args) {int i = 8; //i = i++; i = ++i; System.out.println(i); }}
执行结果为:
9i=++i字节码解读
0 bipush 8
把数值8压入操作数栈,压栈前转为int类型。
2 istore_1
8出栈,存到编号为1的局部变量表。
文章图片
图:编号为1的局部变量为1
以上两行指令,完成了int i = 8; 这行代码。
3 iinc 1 by 1
把局部变量表中的i,进行+1操作。此时,局部变量表中i为9。
6 iload_1
从局部变量表,获取int值9。然后压到操作数栈。
7 istore_1
9出栈,存到编号为1的局部变量表。也就是赋值给i变量。
参考 Chapter 6. The Java Virtual Machine Instruction Set
总结
i=i++
和i=++i
,第3、4行位置是相反的。i++
是先执行iload_1
,再执行iinc 1 by 1。
iload_1:
从局部变量表,获取int值8。然后压到操作数栈。iinc 1 by 1
:把局部变量表中的i,进行+1操作。此时栈里面数值是8,局部变量表中i为9。istore_1
时,获取的是栈中的8,所以最后结果为8。而
++i
,是先执行iinc 1 by 1
,再执行iload_1
。iinc 1 by 1
: 把局部变量表中的i,进行+1操作。此时,局部变量表中i为9。【一篇文章带你从java字节码层理解i++和++i】
iload_1
:从局部变量表,获取int值9。然后压到操作数栈。istore_1
时,获取的是栈中的9,所以最后结果为9。本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- 宽容谁
- 一个人的旅行,三亚
- 第6.2章(设置属性)
- 布丽吉特,人生绝对的赢家
- 家乡的那条小河
- 讲述,美丽聪明的海欧!
- PMSJ寻平面设计师之现代(Hyundai)
- 夜游宫|夜游宫 心语
- 增长黑客的海盗法则
- 画画吗()