在一些程式語言,像是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
Justin
在呼叫
some()
方法時傳入了c1
,這表示將c1
參考的物件,也讓some()
方法的參數c參考,用圖表示就是:在
some()
方法中c.name = "John"
,就是要求將c
參考物件的name
成員指定為"John"
,結果就是:some()
方法執行結束後,c
變數不存在了。下一行取得c1.name
並顯示,依上圖來看,當然就是顯示John。接著看
other()
方法呼叫時傳入了c2
,這表示將c2
參考的物件,也讓other()
方法的參數c參考,用圖表示就是:在
other()
方法中c = new Customer("Bill")
,就是要求建立新物件,並指定給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++之類語言中的「參考」,在根本就是不同的定義,只不過剛好都叫作「參考」罷了!