源起:
最近在学jvm,碰到一道分析题,用字节码指令分析++i 和 i++的区别,相信大家对++i 和 i++的区别应该非常熟悉,但是具体为什么会这样可能还是一知半解,这篇分享和大家共同解惑。
代码:
代码非常简单,这里就只分析question02了,下面的内容如果不熟悉局部变量表和操作数栈的可能不太容易理解。
public void test03(){
// question01
int i1 = 10;
i1++;
int i2 = 10;
++i2;
//question02
int i3 = 10;
int i4 = i3++;
int i5 = 10;
int i6 = ++i5;
//question03
int i7 = 10;
i7 = i7++;
int i8 = 10;
i8 = ++i8;
//question04
int i9 = 10;
int i11 = 10;
int i10 = i9++ + ++i9;
int i12 = ++i11 + i11++;
}
字节码:
我用的是jclasslib插件看的字节码,但是不知道为啥,里面字体很小,如果朋友们知道怎么处理,请务必分享给我,十分感谢!!!
分析第7到第11行:
首先 bipush 把i3压入操作数栈,然后 istore_3 把这个值存到局部变量表,到这里,int i3 = 10;这句话就执行完毕了,接下来重点来了, iload_3 然后iinc 3 by 1 表示先把i3取到了操作数栈,然后在局部变量表中自增一,最后istore 4 把操作数栈中的i3存入局部变量表,因为自增行为绕过了操作数栈,所以istore 4时存的值为10,而不是自增后的值。
分析第12到16行
12,13行和第7,8行的操作是一样的,不再赘述,重点是第14-16行,14:iload_5 然后iinc 3 by 1 :先在局部变量表中自增,然后iload 5,把自增后的值读到操作数栈中,最后istore 6 存到一个新的局部变量中,这样就完成了先自增再存储。我相信这里能理解的话,下面的也没问题了,大家可以自己去看看。