一、描述
想必大家对i++;++i
的问题一定不会陌生;例如:
int j=0;
for(int i=0;i<100;i++) {
j=j++;
}
System.out.println("j="+j);
但是联系之前写的一篇 JAVA 连等赋值问题 的博客,原以为产生差别的原因是栈中的引用导致的,结果查看 class 字节码后发现不是,所以在这里再分析一下;
二、分析
1. ++i
int j, i = 0;
j = ++i;
使用 javap -v .class
查看字节码;也可以使用 Jclasslib
(一款 Class 文件的编辑器);
Code:
stack=1, locals=3, args_size=1
0: iconst_0 // 将0压入操作数栈
1: istore_2 // 将0存入本地变量表2的位置
2: iinc 2, 1 // 本地变量表位置2加1
5: iload_2 // 载入本地变量表2位置到操作数栈
6: istore_1 // 存入本地变量表位置1
7: return
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 args [Ljava/lang/String;
7 1 1 j I // j 为本地变量表1
2 6 2 i I // i 为本地变量表2
如图:
所以最终结果是: i=1;j=1;
2. i++
int j, i = 0;
j = i++;
同样需要查看字节码;
Code:
stack=1, locals=3, args_size=1
0: iconst_0
1: istore_2
2: iload_2
3: iinc 2, 1
6: istore_1
7: return
LineNumberTable:
line 69: 0
line 70: 2
line 73: 7
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 args [Ljava/lang/String;
7 1 1 j I
2 6 2 i I
所以最终结果是:i=1;j=0;
总结
- 最终对比会发现 i++ 和 ++i,只有
iload_2
的位置不一样;使得最终回写到 j 位置的值不一样; - 文中字节码的含义是在《Java 虚拟机规范》中查找的;