當一個對象被當作參數傳遞到一個方法後,在此方法內可以改變這個對象的屬性,那麼這裡到底是值傳遞還是引用傳遞? 答:是值傳遞。Java 語言的參數傳遞只有值傳遞。當一個實例對象作為參數被傳遞到方法中時,參數的值就是該對象的引用的一個副本。指向同一個對象,對象的內容可以在被調用的方法內改變,但對象的引用( ...
當一個對象被當作參數傳遞到一個方法後,在此方法內可以改變這個對象的屬性,那麼這裡到底是值傳遞還是引用傳遞?
答:是值傳遞。Java 語言的參數傳遞只有值傳遞。當一個實例對象作為參數被傳遞到方法中時,參數的值就是該對象的引用的一個副本。指向同一個對象,對象的內容可以在被調用的方法內改變,但對象的引用(不是引用的副本) 是永遠不會改變的。
Java的參數傳遞,不管是基本數據類型還是引用類型的參數,都是按值傳遞,沒有按引用傳遞!
我們可以看一下microsoft的文檔中對按引用傳遞參數的定義(如下截圖):https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/ref#passing-an-argument-by-reference
1、基本數據類型的參數
先來看一下基本數據類型的參數按值傳遞的例子:
TransferTest.java
public class TransferTest { public static void main(String[] args) { int num = 1; System.out.println("changeNum()方法調用之前:num = " + num); changeNum(num); System.out.println("changeNum()方法調用之後:num = " + num); } public static void changeNum(int x) { x = 2; } }
運行結果:
這個傳遞過程的示意圖如下:
num作為參數傳遞給changeNum()方法時,是將記憶體空間中num所指向的那個存儲單元中存放的值1傳遞給了changeNum()方法中的x變數,而這個x變數也在記憶體空間中分配了一個存儲單元,這個時候,就把num的值1傳遞給了x的這個存儲單元中。此後,在changeNum()方法中對x的一切操作都是針對x所指向的這個存儲單元,與num所指向的那個存儲單元沒有關係了!
所以,在changeNum()方法調用之後,num所指向的存儲單元的值還是沒有發生變化,這就是所謂的“值傳遞”!值傳遞的精髓是:傳遞的是存儲單元中的內容,而不是存儲單元的引用!
2、引用類型的參數
同樣,先看一個例子:
TransferTest2.java
1 public class TransferTest2 { 2 public static void main(String[] args) { 3 Person person = new Person(); 4 System.out.println(person); 5 change(person); 6 System.out.println(person); 7 } 8 9 public static void change(Person p) { 10 p = new Person(); 11 } 12 } 13 14 /** 15 * Person類 16 */ 17 class Person { 18 19 }
運行結果:
可以看出兩次列印person的地址值是一樣的,即調用完change() 方法之後,person變數並沒有發生改變。
這個傳遞過程的示意圖如下:
當執行到第3行代碼時,程式在堆記憶體中開闢了一塊記憶體空間用來存儲Person類的實例對象,同時在棧記憶體中開闢了一個存儲單元用來存儲該實例對象的引用,即上圖中person指向的存儲單元。
當執行到第5行代碼時,person作為參數傳遞給change()方法,需要註意的是:person將自己存儲單元的內容傳遞給了change()方法的p變數!此後,在change()方法中對p的一切操作都是針對p所指向的存儲單元,與person所指向的那個存儲單元沒有關係了!
下一篇文章會分析如何用java語言實現按引用傳遞參數的效果
歡迎轉載,但請保留文章原始出處
本文地址:http://www.cnblogs.com/nnngu/p/8299724.html