Java之使用中間緩存變量機制


  今天在刷題時遇到這么一道題,程序代碼如下:

 1 package algorithms.com.guan.javajicu; 
 2 public class Inc { 
 3     public static void main(String[] args) { 
 4        Inc inc = new Inc(); 
 5        int i = 0; 
 6        inc.fermin(i); 
 7        i= i ++; 
 8        System.out.println(i);
 9     
10     } 
11     void fermin(int i){ 
12        i++; 
13     } 
14 }

此程序運行的結果是:0。這個結果令我非常困惑,令我困惑的問題有兩個:

  1. 為什么調用fermin函數后,不影響i的值?
  2. i=i++;i的值為什么是0?

關於第一個問題的解答如下:

  1. java方法之間的參數傳遞是值傳遞而不是引用傳遞
  2. 每個方法都會有一個棧幀,棧幀是方法運行時的數據結構。這就是說每個方法都有自己獨享的局部變量表。(更嚴謹的說法其實是每個線程在執行每個方法時都有自己的棧幀,或者叫當前棧幀 current stack frame)
  3. 被調用方法fermin()的形式參數int i 實際上是調用方法main()的實際參數 i 的一個副本。
  4. 方法之間的參數傳遞是通過局部變量表實現的,main()方法調用fermin()方法時,傳遞了2個參數:
    第0個隱式參數是當前實例(Inc inc = new Inc(); 就是inc引用的副本,引用/reference 是指向對象的一個地址,32位系統這個地址占用4個字節,也就是用一個Slot來保存對象reference,這里傳遞的實際上是reference的一個副本而不是 reference本身 );
    第1個顯示參數是 i 的一個副本。所以 fermin()方法對 i 執行的操作只限定在其方法獨享或可見的局部變量表這個范圍內,main()方法中局部變量表中的i不受它的影響;
    如果main()方法和fermin()方法共享局部變量表的話,那答案的結果就會有所不同。

關於第二個問題的解答如下:

  Java使用了中間緩存變量機制:
  i=i++;等同於:i++是先將i賦值,然后再自增
  temp=i; (等號右邊的i)
  i=i+1;      (等號右邊的i)
  i=temp;   (等號左邊的i)
  而i=++i;則等同於:
  i=i+1;
  temp=i;
  i=temp;

故調用fermin函數不會影響i的值,所以i=0,然后公式i=i++;i的值依然是0,所以程序運行的結果是0。

本人水平有限以上解釋如有錯誤,歡迎指出,以便修改。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM