方法調用時參數如何傳遞?Java 採用值傳遞,但基本類型與引用類型的「值」含義不同。本文通過代碼實驗徹底釐清這一核心概念,為後續理解對象交互奠基。
public class Test5 {
public void printX(int x) {
x++;
System.out.println("printX: x=" + x); // 11
}
public static void main(String[] args) {
Test5 t = new Test5();
int x = 10;
t.printX(x);
System.out.println("main: x=" + x); // 10
}
}
結論:實參 x=10 的數值被複製給形參,形參自增不影響實參。基本類型變量直接存儲數值,傳遞的是數值副本。
public class Test6 {
public void printName(Student stu) {
System.out.println("printName: " + stu.getName()); // Rose
}
public void printPwd(Student stu) {
stu.setPwd("abcdef");
System.out.println("printPwd: " + stu.getPwd()); // abcdef
}
public static void main(String[] args) {
Test6 t = new Test6();
Student s1 = new Student("Rose");
t.printName(s1);
System.out.println("main: " + s1.getName()); // Rose
Student s2 = new Student("John", "123");
t.printPwd(s2);
System.out.println("main: " + s2.getPwd()); // abcdef ← 被修改!
}
}
class Student { private String name, pwd; /* getter/setter */ }
現象:
printName 只讀取,主方法對象屬性不變printPwd 修改對象內部狀態,主方法看到變化本質:實參 s2 存儲的是對象在堆中的地址值(引用)。傳遞時複製這個地址值給形參,兩個引用指向同一對象。形參雖不可讓實參指向新對象(如 stu = new Student()),但可通過形參修改共享對象的可變狀態。
棧幀 main: s1 ──────► [Student@100: name="Rose"]
s2 ──────► [Student@200: name="John", pwd="123"]
▲
棧幀 printPwd: stu ─────┘ (複製地址值 200)
stu.setPwd("abcdef") 修改堆上 @200 對象的 pwd 字段
| 維度 | 基本類型 | 引用類型 |
|---|---|---|
| 變量存儲 | 數值本身 | 對象地址(引用) |
| 傳遞內容 | 數值副本 | 地址值副本 |
| 方法內修改參數變量 | 不影響外部 | 不影響外部變量指向 |
| 方法內修改對象狀態 | 無對象狀態 | 影響外部可見 |
| 能否讓實參指向新對象 | 不適用 | 不能 |
List、Date、自定義 Bean)時,默認可修改原對象new ArrayList(list)、new Date(date.getTime()))或使用不可變類型