Java 中 i = i++的問題

      int i=0;
      i=i++;
      結果i是多少?
      這是一個經常被提及的問題,答案一直五花八門。
      具體測試一下以說明問題: 
      代碼1:

  1. public class Test{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.          i=i++;
  5.          System.out.println(i);
  6.     }
  7. }

     結果i依然是0.分析其反編譯後的代碼: 
    

  1. public static void main(java.lang.String[]);
  2.   Code:
  3.    0:   iconst_0     //0放到棧頂
  4.    1:   istore_1    //把棧頂的值保存到局部變量1,也就是i中
  5.    2:   iload_1     //把i的值放到棧頂,也就是說此時棧頂的值是0
  6.    3:   iinc    11  //注意這個指令,把局部變量1,也就是i,增加1,這個指令不會導致棧的變化,也就是說局部變量1,即i此時爲1了。
  7.    6:   istore_1     //把棧頂的值(0)保存到局部變量1,也就是讓i爲0了,所以最後i爲0
  8.    7:   getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  9.    10:  iload_1
  10.    11:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  11.    14:  return

值得注意到是i被修改了兩次,第一次是i++;i變爲1,最後一次是i=0;所以結果i是0
代碼2:

  1. public class Test2{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.          int j=0;
  5.          j=i++;
  6.          System.out.println(i);
  7.          System.out.println(j);
  8.     }
  9. }

這個結果肯定都知道,i是1,j是0.同樣看反編譯之後的代碼: 

  1. public static void main(java.lang.String[]);
  2.   Code:
  3.    0:   iconst_0
  4.    1:   istore_1     //i=0
  5.    2:   iconst_0
  6.    3:   istore_2     //j=0
  7.    4:   iload_1      //把i的值放到棧頂,也就是說此時棧頂的值是0
  8.    5:   iinc    11  //局部變量1加1,也就是讓i++了,此時i已經是1了,上面說過,此指令不會導致棧變化
  9.    8:   istore_2     //把棧頂的值(注意是0)存入局部變量2,也就是j中,所以j=0
  10.    9:   getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  11.    12:  iload_1
  12.    13:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  13.    16:  getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  14.    19:  iload_2
  15.    20:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  16.    23:  return

很明顯可以看出,java是先把i的值取出來放到棧頂,我們可以認爲是引入了第三個變量int k=i;然後i++,這時候i爲1了,然後讓j=k;也就是0.結論,i的++運算是在對j這個變量的賦值之前完成的。

代碼3:

  1. public class Test3{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.          int j=0;
  5.          j=++i;
  6.          System.out.println(i);
  7.          System.out.println(j);
  8.     }
  9. }

結果大家也都知道,i=1,j=1
看操作過程: 

  1. public static void main(java.lang.String[]);
  2.   Code:
  3.    0:   iconst_0    
  4.    1:   istore_1    //i=0
  5.    2:   iconst_0
  6.    3:   istore_2     //j=0
  7.    4:   iinc    11   //局部變量i加1,這時候i變成1了 。
  8.    7:   iload_1     //把i的值放到棧頂,棧頂的值是1
  9.    8:   istore_2    //j=1
  10.    9:   getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  11.    12:  iload_1
  12.    13:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  13.    16:  getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  14.    19:  iload_2
  15.    20:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  16.    23:  return

對比代碼2和代碼3,關鍵的差別就是iload_1   個iinc這兩條指令的位置變了。

 

 

當然:如果在C++中:上邊的代碼 運行結果必定是a=10.


轉自:

http://blog.csdn.net/ZangXT/archive/2008/11/05/3229281.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章