Java 方法參數傳遞只有「值傳遞」。 雖然對象傳遞的是引用(地址),但引用本身是按值複製傳遞的。形參與實參佔用不同棧內存空間,形參存儲的是實參引用值的副本。
public class Employee {
public String name;
public Employee(String n) { this.name = n; }
public static void swap(Employee e1, Employee e2) {
Employee temp = e1;
e1 = e2;
e2 = temp;
System.out.println(e1.name + " " + e2.name); // 李四 張三
}
public static void main(String[] args) {
Employee worker = new Employee("張三");
Employee manager = new Employee("李四");
swap(worker, manager);
System.out.println(worker.name + " " + manager.name); // 仍為 張三 李四
}
}
形參 e1、e2 交換了引用副本,不影響實參 worker、manager 的引用值。
main 棧幀局部變量區存儲實參引用 worker、manager(指向堆中對象)。swap 棧幀局部變量區存儲形參引用 e1、e2,初始值與實參相同,但佔用獨立棧槽位。| 傳遞方式 | 內存關係 | 本質 |
|---|---|---|
| 值傳遞 | 形參、實參佔用兩塊獨立內存,形參存實參值的拷貝 | Java 對象傳遞符合此定義(引用值也是值) |
| 引用傳遞 | 形參、實參同一塊內存,只是不同別名 | C/C++ 的 int &ref = a; 別名機制 |
void swap(int *a1, int *b1) {
int *t = a1; a1 = b1; b1 = t; // 僅交換指針副本
}
int main() {
int x1=100, x2=200;
int *a=&x1, *b=&x2;
swap(a,b);
// a,b 指向不變
}
void swap(int &a1, int &b1) { // a1 是 a 別名,b1 是 b 別名
int t = a1; a1 = b1; b1 = t; // 真正交換值
}
「Java 基本類型傳值,對象傳引用」—— 錯誤。對象傳的是引用的值(地址副本)。
「在方法中修改對象屬性會影響原對象」—— 正確。因為形參引用副本指向同一堆對象,修改對象內部狀態可見;但重新賦值形參指向新對象則不影響實參。
Java 唯一參數傳遞機制是值傳遞。理解「引用值也是值」,區分「修改對象狀態」與「改變引用指向」,是避免參數傳遞誤區的關鍵。