Java 唯有值傳遞。當方法參數為物件參考型別時,傳遞的是「參考的副本」(即記憶體地址值)。在方法內修改物件的屬性會影響原物件,但將參數重新指向新物件(如 param = new Obj())則不會影響外部原變數。這與 C++ 的指標/參考傳遞有本質不同。
public class Test {
static class User { String name; }
public static void main(String[] args) {
User u = new User(); u.name = "A";
modifyAttr(u); // 修改屬性
System.out.println(u.name); // 輸出 "B" -> 原物件被改變
reassign(u); // 嘗試重新指向
System.out.println(u.name); // 仍輸出 "B" -> 外部變數 u 未變
}
static void modifyAttr(User user) {
user.name = "B"; // 通過副本參考找到同一物件,修改屬性
}
static void reassign(User user) {
user = new User(); // 區域變數 user 指向新物件
user.name = "C"; // 原物件 u 不受影響
}
}
| 操作 | Java 行為 | C++ 指標傳遞 | C++ 參考傳遞 |
|---|---|---|---|
| 修改物件屬性/成員 | 影響原物件 | 影響原物件 | 影響原物件 |
| 參數重新指向/賦值新物件 | 不影響外部變數 | 不影響外部指標(除非傳指標的指標) | 影響外部變數(別名) |
| 交換兩個物件變數 | 無法在方法內完成 | 傳指標的指標可完成 | 傳參考可完成 |
參考傳遞的定義是:形式參數成為實際參數的別名,對形式參數的任何操作(包括重新賦值)都直接作用於實際參數。Java 中形式參數重新賦值斷開與實際參數的關聯,故非參考傳遞。這只是「傳遞參考的值」(Call by Value of Reference),通稱值傳遞。
AtomicReference、自訂 Holder<T>)。list = new ArrayList() 則不影響。徹底理解「值傳遞參考」機制,能避免 Java 開發中關於參數修改的邏輯錯誤。