程序設計語言中將參數傳遞給方法的幾種方式:
C++ 支持 按值調用 和 按引用調用:
void func(int arg); // 按值調用;
void func(int& arg); // 按引用調用;
而 Java 只支持 按值調用, 也就是說方法得到的是所有參數值的一個拷貝, 在方法內對參數值進行修改是不會影響原值的.
然而方法參數有兩種類型:
當方法參數是 對象引用 時, 在方法很容易的調用其 setXXX
方法修改該對象屬性值, 在退出方法後該修改仍然有效, 但這仍舊只是 按值調用.
因為參數是 對象引用, 在該方法內仍舊執行原對象(類似 C++ 的指針), 調用它的 setXXX
方法當然能修改對象屬性了. 但也僅限於修改對象屬性(狀態), 而不能通過 new
等方式對原對象進行修改.
如果還有疑問, 就請看看這個例子:
class MyObject {
private String name;
MyObject(String name) {
this.name = name;
}
}
staticvoidswap(MyObject first, MyObject second) {
MyObject temp = first;
first = second;
second = first;
}
staticvoidtestSwap() {
MyObject a = new MyObject("a");
MyObject b = new MyObject("b");
swap(a, b);
}
請問在執行 swap()
函數後, 對象 a 和 對象 b 的 name
是否變化?
答案是沒有變化. 在 testSwap()
方法中, first
和 second
完成交換並分別指向對方. 但是, 在進入方法時, 它們拿到的是對象引用的拷貝(位置), 類似於:
swap()
方法前, a
知道在內存地址為 100 的地方存儲了一個 MyObject
對象, 'b' 知道在內存地址為 200 的地方存儲了另一個 MyObject
對象;swap()
方法時, a
將它的對象引用復制一份給 first
, 也就是說 first
知道內存地址為 100 的地方有一個 MyObject
對象. second
同理;swap()
方法時, first
與 second
交換值, 也就是說 first
知道內存地址為 200 的地方有一個 MyObject
對象, 它已經跟內存地址為 100 的 MyObject
對象沒有任何關系了. second
同理;swap()
方法後, first
與 second
被銷毀, a
仍舊是知道內存地址為 100 的地方有一個 MyObject
對象...其實, 這就是 C/C++ 的指針.
順便說一句, 通過 C++ 的 按引用調用 可以很方便實現 swap() 函數. 當然, 用指針也是支持滴, 只不過稍微復雜點(這裡只給出聲明, 有興趣的同學自己去寫實現吧):
MyObject* a = new MyObject("a");
MyObject* b = new MyObject("b");
void swap(MyObject& first, MyObject& second); // C++ 引用
void swap(MyObject **first, MyObject **second); // C/C++ 指針版 swap
綜上, java 中的方法參數: