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

深入理解 Java 參數傳遞:值傳遞與引用傳遞的記憶體模型解析

     編輯:Java 相關知識

Java 只有「值傳遞」一種參數傳遞機制,但基本型別與參考型別在記憶體中的表現截然不同。本文結合堆疊與堆記憶體模型,透過程式碼與圖示詳細解析兩者差異,並釐清 String 的特殊行為。

核心結論

Java 一律採用值傳遞。差別在於「傳遞的值是什麼」:

  • 基本型別:傳遞的是資料值的複製品。
  • 參考型別:傳遞的是物件在堆記憶體中的位址(引用)的複製品。

基本型別參數傳遞

public class ParameterTransfer {
    public static void main(String[] args) {
        int num = 30;
        System.out.println("呼叫前 num = " + num); // 30
        add(num);
        System.out.println("呼叫後 num = " + num); // 30(未改變)
    }

    public static void add(int param) {
        param = 100; // 只修改區域變數副本
    }
}

記憶體模型:

  1. main 堆疊框架分配 num(位址 AD8500),值為 30。
  2. 呼叫 add 時,在堆疊新建框架,分配 param(位址 AD8600),複製值 30。
  3. 修改 param 只影響 AD8600,AD8500 不變。

參考型別參數傳遞

public class ParameterTransfer {
    public static void main(String[] args) {
        String[] array = new String[] {"huixin"};
        System.out.println("呼叫前 array[0] = " + array[0]); // huixin
        reset(array);
        System.out.println("呼叫後 array[0] = " + array[0]); // hello, world!
    }

    public static void reset(String[] param) {
        param[0] = "hello, world!"; // 修改堆中同一物件內容
    }
}

記憶體模型:

  1. main 堆疊 array(AD9500)存放堆位址 BE2500。
  2. 堆 BE2500 存放陣列物件,array[0] 指向字串 "huixin"。
  3. 呼叫 reset,堆疊新建 param(AD9600),複製位址 BE2500。
  4. 兩個引用指向同一堆物件,透過任一引用修改內容,另一端可見。

String 的特殊行為

String 是參考型別,但表現像基本型別:

public static void change(String s) {
    s = "new value"; // 重新指向新物件
}
String str = "old";
change(str);
System.out.println(str); // 仍輸出 "old"

原因有二:

  1. 不可變性:String 內部封裝 char[],任何「修改」操作實際上都是建立新物件。
  2. 引用重新指向:方法內 s = "new value" 只是讓區域變數 s 指向新字串物件,不影響呼叫端的 str 引用。

總結

型別類別傳遞內容方法內修改參數本身方法內修改物件內容
基本型別值的複製不影響原變數不適用
參考型別引用(位址)的複製不影響原引用指向影響原物件(共享堆記憶體)
String引用的複製不影響原引用不可修改內容,操作產生新物件

理解記憶體模型是掌握 Java 參數傳遞本質的關鍵:無論何種型別,傳遞的都是「值」的副本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved