首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 參數傳遞機制真相:只有值傳遞,沒有引用傳遞

     編輯:Java 相關知識

Java 官方規範明確:Java 只有值傳遞 (Call by Value)。所謂「物件傳引用」實為「傳遞參考的副本」。本文透過兩個經典案例徹底釐清誤區。

案例一:String 不可變物件


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";  // 修改區域變數指向
    }
}

記憶體模型分析

  1. name 指向字串常量池中 "123"
  2. 呼叫 change(),str 複製 name 的參考值(地址),雙方指向同一 "123"
  3. str = "234" 讓 str 指向新常量 "234",name 不受影響
  4. 方法結束,str 消亡,name 仍指向 "123"

案例二:可變物件 StringBuilder


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");  // 修改物件內部狀態
    }
}

關鍵差異

  1. sb 與 str 指向同一堆上物件
  2. append() 修改的是**物件內容**,非參考指向
  3. 參考未變,故呼叫端可見變更

統一解釋模型

參數類型傳遞內容方法內可修改呼叫端可見
基本型別值的副本區域變數值不可見
物件參考參考的副本(地址值)① 參考指向(不可見)
② 物件內部狀態(可見)
僅②可見

對比 C++ 指標/引用


// C++ 真正的引用傳遞
void cppRef(int &ref) { ref = 20; }  // 直接修改原變數
// C++ 指標傳遞
void cppPtr(int *ptr) { *ptr = 20; } // 解引用修改

Java 無指標、無 & 引用參數語法,無法在方法內修改呼叫端的參考變數本身(如讓 name 指向新物件)。

實務建議

  1. 不可變物件(String、Integer、LocalDate 等)天然線程安全,傳遞無副作用
  2. 可變物件(集合、StringBuilder、自訂 Bean)傳遞時注意防禦性複製
  3. 需修改呼叫端參考指向時,改為回傳新物件或使用容器包裝(AtomicReference、單元素陣列)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved