从字节码来分析,i++与++i区别

++/-- 是一种特殊的算术运算符,在算术运算符中需要两个操作数来进行运算,而自增自减运算符是一个操作数

前缀自增(++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。

猜你喜欢

转载自www.cnblogs.com/song27/p/12359702.html