標籤:沒有 歸併 str 輸出 一段 傳引用 bsp 方法 ati
最近在讀《演算法導論》,在嘗試自己實現歸併排序時,發現了一個很奇怪的問題。
為了能夠專註於問題,下面使用一段重新編寫的能夠重現問題的代碼。可以嘗試運行一下。
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在傳參數時是複製指標,但不進行進一步複製。那麼,在執行上述代碼的第七行時,應當發生了這些:
- Java複製tmp變數的指標,將複製過的指標作為src交由test方法使用。注意,此時tmp與src指向同一個對象,但它們並不是同一個指標。
- 程式一路執行到第十六行,這時src的值(地址)被out替代。
- 執行到第十七行時,由於此時的src是原先的out,故列印出1 2 3。
- test方法執行完畢,src被銷毀。
在以上過程中,由於被改變的是tmp的引用副本(即src),故tmp所指向的對象並未發生任何改變。原先的src與out所指向的對象已經失去所有指向其自身的指標,即將在不久後被銷毀。而在數組逐元素複製中,src雖然是一個副本,但針對其所指向的對象所作的修改只依賴於指標所指向的對象而非指標本身,故此修改能夠反映到tmp中。
參考文章:java中的經典問題:傳值與傳引用
另外最近成功用VPS建了個獨立的部落格,點擊這裡進入。
由傳值、傳引用引發的問題 (Java)