理解值傳遞和引用傳遞

首先,其實不管是值傳遞還是引用傳遞,其實都是值傳遞,都是副本。就像Think in Java裏面說的:

I read in one book where it was “completely wrong to say that Java supports pass by reference,” because Java object identifiers (according to that author) are actually “object references.” And (he goes on) everything is actually pass by value. So you’re not passing by reference, you’re “passing an object reference by value.” One could argue for the precision of such convoluted explanations, but I think my approach simplifies the understanding of the concept without hurting anything (well, the language lawyers may claim that I’m lying to you, but I’ll say that I’m providing an appropriate abstraction).

上面的話其實就是在說,對於對象的形參而言,我們好像是在傳遞一個對象,然而實際上我們只是傳遞一個對象的引用(棧空間裏)而不是對象本身(堆裏的實際對象)。這裏我們可以把其稱爲引用變量,引用變量和值變量都是值傳遞,都是副本。
這裏寫圖片描述

如果以上還是理解不了大可以將方法參數接收分解爲一系列賦值操作。

public class Ref{
    public static void main(String[] args){
      Person p = new Person();
      change(p);
    }
    public void change(Person p){//這裏的p其實可以任意取名字,比如a,b,c....
       System.out.println(p);
    }
}

當調用change()時候可等效於這樣一個過程:

public void change(Person person = p){//這裏就是等效的過程
    System.out.println(person);
}

根據以上理解來看下這個示例:

public class Test{
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("123");
        change(str);
        System.out.println(str);
    }
    public static void change(StringBuffer str){
        str= new StringBuffer("abc");
    }
}

錯誤輸出:abc
正確輸出:123
等效過程:

public class Test{
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer("123");
        change(str);
        System.out.println(str);
    }
    public static void change(StringBuffer str = str){//注意這裏的等號左右的str並不是同一個str
        str = new StringBuffer("abc");
    }
}

當調用方法的時候,等號左邊的是形參,右邊的是你傳入的,他們是兩個引用變量,他們除了指向同一個對象,並沒有其他關係,而在方法內

str = new StringBuffer("abc");

使得形參str指向了新的對象,但傳入的str並沒有改變。所以最後輸出的時候還是123
結論:Java中都是值傳遞

發佈了35 篇原創文章 · 獲贊 12 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章