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的參數傳值方式是值傳遞,而非引用傳遞。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章