在Java學習中,“方法參數傳遞到底是值傳遞還是引用傳遞”是一個常見的困惑點。很多初學者會覺得,既然傳遞的是對象(引用類型),那就是“引用傳遞”;但實際上,Java中所有參數傳遞本質上都是值傳遞。今天我們用最簡單的例子,幫你徹底搞懂這個問題。
一、先明確概念:值傳遞 vs 引用傳遞¶
- 值傳遞:方法接收的是參數的“副本”,對參數的修改不會影響原變量。比如你把一張紙條(值)遞給別人,別人寫了字,不會改變你手裏的紙條。
- 引用傳遞:方法接收的是參數的“引用地址”(類似“鑰匙”),對參數的修改會直接影響原對象。比如你把鑰匙(引用)給別人,別人用鑰匙打開原鎖(對象)並修改內容,原鎖的內容會變。
關鍵區別:值傳遞修改的是“副本”,引用傳遞修改的是“原對象”。但Java中不存在嚴格意義的“引用傳遞”,只有“值傳遞”。
二、基本類型參數:值傳遞的直接體現¶
Java中的基本類型(如int、double、boolean等)傳遞時,方法接收的是值的副本。修改參數不會影響原變量。
例子:交換兩個int變量的值¶
public class ValuePassDemo {
// 定義交換方法
public static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
public static void main(String[] args) {
int x = 10;
int y = 20;
swap(x, y); // 調用方法
System.out.println("x=" + x + ", y=" + y); // 輸出:x=10, y=20
}
}
爲什麼結果沒變?
swap方法中的a和b是x和y的“副本”。修改a和b(交換)只改變了副本,原變量x和y不受影響。
三、引用類型參數:容易混淆的“陷阱”¶
Java中的引用類型(如對象、數組、接口等)傳遞時,方法接收的是引用地址的副本。雖然修改的是“地址副本”,但由於副本和原引用指向同一個對象,因此修改對象的屬性會影響原對象。
誤區1:修改對象屬性會影響原對象 → 誤認爲是“引用傳遞”¶
class Student {
String name;
public Student(String name) {
this.name = name;
}
}
public class ReferencePassDemo {
// 方法:修改Student對象的name屬性
public static void changeName(Student s) {
s.name = "小明"; // 修改對象屬性
}
public static void main(String[] args) {
Student s = new Student("小紅");
changeName(s); // 傳遞對象引用
System.out.println(s.name); // 輸出:小明(原對象屬性被修改)
}
}
真相:
changeName方法接收的是Student對象引用的副本(副本和原引用s指向同一個Student對象)。修改name屬性時,實際上是修改了“同一個對象”的內容,因此原對象的屬性會變。這是因爲引用地址的副本和原引用指向同一對象,而非“引用傳遞”。
誤區2:修改引用本身 → 原對象不受影響¶
如果在方法中修改引用本身(讓引用指向新對象),原對象不會變,這更能證明是“值傳遞”:
public static void changeReference(Student s) {
s = new Student("小剛"); // 修改引用指向新對象
}
public static void main(String[] args) {
Student s = new Student("小紅");
changeReference(s); // 傳遞原引用
System.out.println(s.name); // 輸出:小紅(原對象未被修改)
}
爲什麼結果沒變?
changeReference中的Student s是原引用的“副本”,修改副本指向新對象,原引用main中的s仍指向“小紅”。這就是值傳遞的本質:修改的是“引用地址的副本”,而非原引用本身。
四、總結:Java永遠是“值傳遞”¶
- 基本類型:傳遞“值的副本”,修改副本不影響原變量。
- 引用類型:傳遞“引用地址的副本”,修改副本指向的對象屬性會影響原對象(因爲它們指向同一對象),但修改引用本身(指向新對象)不會影響原對象。
核心結論:Java中所有參數傳遞都是值傳遞,不存在“引用傳遞”。引用類型的特殊性在於“地址副本”和“原對象共享”,而非傳遞方式本身是“引用傳遞”。
一句話記住:¶
- 值傳遞:傳的是“副本”,改副本不影響原;
- 引用類型:傳的是“地址副本”,共享對象,改屬性影響原。
Java永遠是“值傳遞”!