Java **只有按值傳遞**。無論基本型別還是參考型別,方法收到的都是**實參值的副本**。
直接包含數值。副本修改不影響原變數。
public static void changePrimitive(int p) { p = 3; }
int primitive = 2;
changePrimitive(primitive);
// primitive 仍為 2
變數儲存的是**物件在堆上的位址(引用值)**。傳遞的是**引用值的副本**。
public static void changeObject(MyClass obj) { obj.i = 3; }
MyClass mc = new MyClass(); mc.i = 1;
changeObject(mc);
// mc.i 變為 3
public static void changeObject(MyClass obj) { obj = new MyClass(); }
MyClass mc = new MyClass();
changeObject(mc);
// mc 仍指向原物件
public class ParameterPassingDemo {
public static void main(String[] args) {
// 基本型別
int primitive = 2;
changePrimitive(primitive);
System.out.println("primitive = " + primitive); // 2
// 參考型別:修改內部狀態
MyClass obj1 = new MyClass();
obj1.i = 1;
changeObjectState(obj1);
System.out.println("obj1.i = " + obj1.i); // 3
// 參考型別:重新指向
MyClass obj2 = new MyClass();
obj2.i = 1;
changeObjectRef(obj2);
System.out.println("obj2.i = " + obj2.i); // 1 (未變)
System.out.println("obj2 == original? " + (obj2 == originalRef)); // true
}
static void changePrimitive(int p) { p = 3; }
static void changeObjectState(MyClass obj) { obj.i = 3; }
static MyClass originalRef; // 用於驗證引用是否改變
static void changeObjectRef(MyClass obj) {
originalRef = obj; // 保存原引用
obj = new MyClass(); // 參數指向新物件
obj.i = 99;
}
}
class MyClass { int i; }
遠端介面傳遞參數時,無論型別,**一律進行序列化/反序列化**,客戶端與伺服器端擁有**獨立物件副本**,雙向修改互不影響(除非使用遠端物件引用 Remote)。本地介面則同本地語義。
棧幀 (main) 堆
+-----------+ +-----------------+
| primitive | 2 | |
+-----------+ | MyClass@1234 |← obj1, 參數 obj (同一引用值)
| obj1 | ──────→| i = 1 → 3 |
+-----------+ +-----------------+
| obj2 | ──────→| MyClass@5678 |← obj2
+-----------+ | i = 1 | 參數 obj → 新建 MyClass@9999 (i=99)
+-----------------+ obj2 仍指向 @5678