Java 官方規範明確:Java 只有值傳遞 (Call by Value)。所謂「物件傳引用」實為「傳遞參考的副本」。本文透過兩個經典案例徹底釐清誤區。
public class StringDemo {
public static void main(String[] args) {
String name = "123";
change(name);
System.out.println(name); // 輸出:123
}
static void change(String str) {
str = "234"; // 修改區域變數指向
}
}
name 指向字串常量池中 "123"change(),str 複製 name 的參考值(地址),雙方指向同一 "123"str = "234" 讓 str 指向新常量 "234",name 不受影響str 消亡,name 仍指向 "123"
public class StringBuilderDemo {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("123");
modify(sb);
System.out.println(sb); // 輸出:123234
}
static void modify(StringBuilder str) {
str.append("234"); // 修改物件內部狀態
}
}
sb 與 str 指向同一堆上物件append() 修改的是**物件內容**,非參考指向| 參數類型 | 傳遞內容 | 方法內可修改 | 呼叫端可見 |
|---|---|---|---|
| 基本型別 | 值的副本 | 區域變數值 | 不可見 |
| 物件參考 | 參考的副本(地址值) | ① 參考指向(不可見) ② 物件內部狀態(可見) | 僅②可見 |
// C++ 真正的引用傳遞
void cppRef(int &ref) { ref = 20; } // 直接修改原變數
// C++ 指標傳遞
void cppPtr(int *ptr) { *ptr = 20; } // 解引用修改
Java 無指標、無 & 引用參數語法,無法在方法內修改呼叫端的參考變數本身(如讓 name 指向新物件)。
AtomicReference、單元素陣列)