1. 程式人生 > >Java的引數傳遞到底是引用傳遞還是值傳遞

Java的引數傳遞到底是引用傳遞還是值傳遞

首先看一段程式碼:

public static void main(String[] args) {
    Person a = new Person(23, "a");
    Person b = new Person(22,"b");
    System.out.println("改變前a:"+a+"\nb:"+b);
    changeValue(a,b);
    System.out.println("改變後a:"+a+"\nb:"+b);
}

private static void changeValue(Person a, Person b) {
    a.setAge(10
); b.setAge(11); }

輸出:
改變前a:Person [age=23, name=a] b:Person [age=22, name=b]
改變後a:Person [age=10, name=a] b:Person [age=11, name=b]

然後我們要明確一下值傳遞和引用傳遞的概念:

值傳遞:方法呼叫時,實際引數把它的值傳遞給對應的形式引數,方法執行中形式引數值的改變不影響實際引數的值。
引用傳遞:也稱為傳地址。方法呼叫時,實際引數的引用(地址,而不是引數的值)被傳遞給方法中相對應的形式引數,在方法執行中,對形式引數的操作實際上就是對實際引數的操作,方法執行中形式引數值的改變將會影響實際引數的值。
參考

部落格園

我們都知道,Java的方法傳遞的是物件引用,形參和實參指向同一個物件的記憶體地址,所以形參修改物件的狀態時,實參指向的物件狀態也會發生變化。

上面的例項很容易讓人認為Java是引用傳遞,因為形參物件的狀態改變直接反應在實參物件上了!

再看一段程式碼:

public static void main(String[] args) {
    Person a = new Person(23, "a");
    Person b = new Person(22,"b");
    System.out.println("交換前a:"+a+"\nb:"+b);
    swap(a, b);
    System.out
.println("交換後a:"+a+"\nb:"+b); } private static void swap(Person a, Person b) { Person temp = a; a = b; b = temp; }

輸出:
交換前a:Person [age=23, name=a] b:Person [age=22, name=b]
交換後a:Person [age=23, name=a] b:Person [age=22, name=b]

很奇怪吧! 為什麼a和b的值沒有交換呢? 按照Java是引用傳遞的假設,a和b的指向的物件會發生交換啊!

很多程式設計語言(特別是C++和Pascal)提供了兩種引數傳遞的方式:值傳遞和引用傳遞。有些程式猿(甚至本書的作者)認為Java對物件採用的是引用傳遞,實際上,這種理解是不對的。–《Core Java Volume I》第9版P122

實際上,結合上面一個例項和值傳遞引用傳遞的概念,我們可以發現,Java方法的傳值,實際上是把實參的值—-物件引用(物件的記憶體地址)傳遞給了形參,從而形參和實參的值(即變數裡儲存的記憶體地址,非變數本身的記憶體地址)是相同的,指向了同一個物件/記憶體地址

所以我們得到如下結論:Java的引數傳值方式是值傳遞,而非引用傳遞。