1. 程式人生 > >由傳值、傳引用引發的問題 (Java)

由傳值、傳引用引發的問題 (Java)

問題 public 傳參 打印 之前 java pre println pri

最近在讀《算法導論》,在嘗試自己實現歸並排序時,發現了一個很奇怪的問題。

為了能夠專註於問題,下面使用一段重新編寫的能夠重現問題的代碼。可以嘗試運行一下。

 1 public class Main
 2 {
 3  public static void main(String[] args)
 4  {
 5   int[] tmp = {4, 5, 6};
 6   Test.print(tmp);
 7   Test.test(tmp);
 8   Test.print(tmp);
 9  }
10 }
11 class Test {
12  public static void test(int
[] src) { 13 int[] out = {1, 2, 3}; 14 print(out); 15 src = out; 16 print(src); 17 } 18 public static void print(int[] src) { 19 for(int i : src) { 20 System.out.print(i + "\t"); 21 } 22 System.out.println(); 23 } 24 }

之前有聽說Java是傳引用的,且在上述例子中,若將test中的 src = out 改為數組逐元素復制,則最後一行輸出將會變為 4 5 6 ,因而一開始並沒有想到這方面的問題。然而,拿著這段代碼問一位學長時(在此特別感謝符學長),得到答復稱Java為傳值。於是當時就迷糊了,決定對此詳細了解一番。

經過查閱相關資料,了解到Java在傳參數時是復制指針,但不進行進一步復制。那麽,在執行上述代碼的第七行時,應當發生了這些:

  1. Java復制tmp變量的指針,將復制過的指針作為src交由test方法使用。註意,此時tmp與src指向同一個對象,但它們並不是同一個指針。
  2. 程序一路執行到第十六行,這時src的值(地址)被out替代。
  3. 執行到第十七行時,由於此時的src是原先的out,故打印出1 2 3。
  4. test方法執行完畢,src被銷毀。

在以上過程中,由於被改變的是tmp的引用副本(即src),故tmp所指向的對象並未發生任何改變。原先的src與out所指向的對象已經失去所有指向其自身的指針,即將在不久後被銷毀。而在數組逐元素復制中,src雖然是一個副本,但針對其所指向的對象所作的修改只依賴於指針所指向的對象而非指針本身,故此修改能夠反映到tmp中。

參考文章:java中的經典問題:傳值與傳引用

另外最近成功用VPS建了個獨立的博客,點擊這裏進入。

由傳值、傳引用引發的問題 (Java)