第一种情况: i++ 和 ++i 单独使用
/**
* 0 bipush 10
* 2 istore_1
* 3 iinc 1 by 1
* 6 return
*/
public void plusPlusNum() {
int i = 10;
++i;
}
/**
* 0 bipush 10
* 2 istore_1
* 3 iinc 1 by 1
* 6 return
*/
public void numplusPlus() {
int i = 10;
i++;
}
从字节码看,两者没有区别,完全一样,都是【iinc 1 by 1】。
第二种情况: 结算结果赋值给另一个变量
/**
* 0 bipush 10
* 2 istore_1
* 3 iload_1
* 4 iinc 1 by 1
* 7 istore_2
* 8 bipush 20
* 10 istore_3
* 11 iinc 3 by 1
* 14 iload_3
* 15 istore 4
* 17 return
*/
public void plusPlusNums() {
int i = 10;
int a = i++;
int j = 20;
int b = ++j;
}
- i++ iload_1把局部变量表i的值10取到操作数栈后,把局部变量表的i加1,此时i确实变成11了,但是第七条指令 istore_2才是把操作数栈的10存入到局部变量表2的位置,即a的值,此时还是10
- ++i 先执行了iinc 3 by 1指令,把局部变量表的i已经加1了,再加载到操作数栈,然后再把栈中的11存入局部变量表4的位置,即b的值,此时就是11
一个有意思的问题:
/**
* 0 bipush 10
* 2 istore_1
* 3 iload_1
* 4 iinc 1 by 1
* 7 istore_1
* 8 getstatic #2 <java/lang/System.out : Ljava/io/PrintStream;>
* 11 iload_1
* 12 invokevirtual #3 <java/io/PrintStream.println : (I)V>
* 15 return
*/
public void iPlusPlus() {
int i = 10;
i = i++;
System.out.println(i); //10
}
过程分析:
1,iload_1 加载i,此时为10到操作数栈
2,iinc 1 by 1 把局部变量表的i 加了变成11
3,istore_1 又把操作数栈的值10存入局部变量表1,即覆盖了11,所以值还是10