Java是pass-by-value(傳值),不是pass-by-reference(傳址/傳參考)。
通常對原始型別的參數值傳遞比較沒什麼疑問,是pass-by-value;但對於物件參數的傳遞就容易感到混淆,常誤以為是pass-by-reference,但Java物件參數的傳遞其實也是pass-by-value。
會混淆是因為沒弄清楚pass-by-reference的意思:
- pass-by-value的意思是將參數值複製後傳遞。
- pass-by-reference的意思是傳遞原本的參數值。
簡單說,pass-by-value和pass-by-reference的差別在於傳遞的是「複製的參數」還是「原本的參數」,若傳遞的是複製的參數則為pass-by-value,若沒複製而是傳遞原來的參數則為pass-by-reference。
public class Main {
public static void main(String[] args) {
A a1 = new A(1);
System.out.println("a1:" + a1.getN()); // a1:1
modify(a1);
System.out.println("a1:" + a1.getN()); // a1:3
}
static void modify(A a) {
a.setN(3);
System.out.println("a:" + a.getN()); // a:3
}
}
class A {
private int n;
public A(int n) {
this.n = n;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
}
你可能會覺得奇怪,傳入方法a
物件參數的值一旦被修改,a1.n
的值也會同時改變,因為a1
和a
兩著都有一樣的參照(reference),應該是pass-by-reference才對吧?
其實上面的情況是,「參照(reference)的pass-by-value的傳遞」,而不是pass-by-reference。這細微的查別在於當呼叫modify(A a)
時是將a1
的reference複製然後傳給a
,因此a1
及a
會擁有相同「內容」的reference(但並不是同一個reference),即所指的位置相同,所以修改a1.n
時,a.n
也會被修改。而不是將a1
參照所指的真正的內容(物件)傳給a
,因為Java變數僅儲存物件的參照,而非物件本身。
總之記住Java是pass-by-value,不是pass-by-reference。
菜鳥工程師-肉豬
沒有留言:
張貼留言