傳值呼叫


在一些程式語言,像是C++之類的程式語言,呼叫方法傳遞引數給參數時,可以有傳值呼叫(Call by value)或傳參考呼叫(Call by reference)的方式。Java當中只有傳值呼叫。傳值呼叫也簡稱傳值(Pass by value),傳參考呼叫也簡稱傳參考(Pass by reference)。


如果沒有接觸過具有傳值呼叫與傳參考呼叫選項的程式語言,瞭解傳值呼叫這個名詞,對你學習Java並沒有太大意義。如果你有接觸過C++這類可傳值與傳參考的語言,注意!C++這類語言中「參考」此一名詞的定義,跟Java中的「參考」並不相同

在Java中,呼叫方法傳遞物件時要注意的事項,只不過是之前「認識物件」相關文章的觀念延伸。舉例來說,你覺得以下程式執行的顯示結果為何?

package cc.openhome;
public class CallByValue {
    public static void main(String[] args) {
        Customer c1 = new Customer("Justin");
        some(c1);
        System.out.println(c1.name);
        
        Customer c2 = new Customer("Justin");
        other(c2);
        System.out.println(c2.name);
    }

    static void some(Customer c) {
        c.name = "John";
    }
    
    static void other(Customer c) {
        c = new Customer("Bill");
    }
}

class Customer {
    String name;
    Customer(String name) {
        this.name = name;
    }
}

先來看執行結果:

John
Justin

在呼叫some()方法時傳入了c1,這表示將c1參考的物件,也讓some()方法的參數c參考,用圖表示就是:

c1與參數c參考同一物件


some()方法中c.name = "John",就是要求將c參考物件的name成員指定為"John",結果就是:

將c參考物件的name指定為"John"


some()方法執行結束後,c變數不存在了。下一行取得c1.name並顯示,依上圖來看,當然就是顯示John。

接著看other()方法呼叫時傳入了c2,這表示將c2參考的物件,也讓other()方法的參數c參考,用圖表示就是:

 c2與參數c參考同一物件


other()方法中c = new Customer("Bill"),就是要求建立新物件,並指定給c參考,結果就是:

c參考至新建的物件


some()方法執行結束後,c變數不存在了,下一章會談到,原本c參考的物件會被JVM清除。下一行取得c2.name並顯示,依上圖來看,當然就是顯示Justin。

這樣的行為就是傳值,以上示範的是傳遞物件給參數的情況,如果由方法中傳回物件,並指定給變數,也是這種行為。例如:

public Customer create (String name) {
    Customer c = new Customer(name);
    ...
    return c;
}

public void doService() {
    Customer customer = create("Irene");
    ...
}

在這個程式片段中,doService()方法中呼叫了create()方法,在create()方法結束後,customer參考的物件與create()執行過程中c參考的物件是同一物件。

這樣的行為確實就是傳值,而不是傳參考,再次強調,Java中的「參考」與C++之類語言中的「參考」,在根本就是不同的定義,只不過剛好都叫作「參考」罷了