++/-- 是一种特殊的算术运算符,在算术运算符中需要两个操作数来进行运算,而自增自减运算符是一个操作数
前缀自增(++a):先进行自增运算,再进行表达式运算;
后缀自增(a++):先进行表达式运算,再进行自增运算。
int x = 5, y=5; int a = 2*++x; int b = 2*y++; System.out.println(a+"=="+b);
输出结果:a = 12, b =10;
前缀++,先自增运算,=》 a=2*6
后缀++,先表达式运算,=》b=10;
1 public void prefixAdd(){ 2 int i = 100; 3 i = ++i; 4 System.out.println(i); 5 } 6 7 public void postfixAdd(){ 8 int i = 100; 9 i = i++; 10 System.out.println(i); 11 } 12 13 public void varAdd(){ 14 int i = 100; 15 int y = i++; 16 System.out.println(i+"=="+y); 17 }
这里比较让人困扰的是第二与第三个方法的区别。这需要从编译的字节码到底层数据分布来查看。
iload_1 :从栈帧的局部变量读取,1表示索引
istore_1:存储到局部变量,1表示索引
iinc:局部变量增加一个常量值
前缀++与后缀++的区别:
当进行到第7行时,istore_1存储的值还是100, 并且覆盖掉已经增加到101的局部变量1。 因此当11行,再次iload_1还是100。
前缀++ 第3行进行了局部变量增加,第6行读取时已经是101,第7行再次存储到局部变量1也是101,因此第11读取时也是101。
后缀++: 先读取局部变量,再进行局部变量增加
前缀++:先局部变量增加,再读取。
第三个方法,使用一个变量把第一次iload_1的值(i=100)存储到istore_2中局部变量中,所以局部变量1的值是101,并没有被覆盖。
因此输出结果:
101
100
101==100
i = i++; ---> int y = i++;这样转变下,就能更好地理解,i = i++; 为什么i=100。