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

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

     編輯:Java 相關知識

經典困惑

「Java 是傳值還是傳引用?」

  • 基本類型:公認傳值。
  • 引用類型(對象、數組):眾說紛紜,甚至面試必考陷阱題。

結論:Java 永遠是「按值調用」。 對於引用類型,傳遞的是引用的副本(值),而非引用本身。

代碼驗證


public class Swap {
    public static void main(String[] args) {
        Changer c = new Changer();

        // 1. 嘗試交換兩個 String
        String stra = "Mighty";
        String strb = "Mouse";
        c.swap(stra, strb);
        System.out.println(stra + " " + strb);  // 輸出:Mighty Mouse(未交換)

        // 2. 嘗試交換數組元素
        String[] strArr = {stra, strb};
        c.swap(strArr);
        System.out.println(strArr[0] + " " + strArr[1]);  // 輸出:Mouse Mighty(交換成功!)
    }

    static class Changer {
        public  void swap(T a, T b) {  // 傳遞引用副本
            T temp = a; a = b; b = temp;  // 僅改變局部變量指向
        }
        public  void swap(T[] t) {     // 傳遞數組引用副本
            if (t.length < 2) return;
            T temp = t[0]; t[0] = t[1]; t[1] = temp; // 修改數組內部內容
        }
    }
}

記憶體模型圖解

記憶體佈局圖

  • stra、strb 棧上存儲引用(地址),指向堆上兩個 String 對象。
  • strArr 棧上存儲引用,指向堆上數組對象,數組內部存儲兩個引用指向同兩個 String。

逐步執行分析

swap(stra, strb)

  1. 調用時,將 stra 的引用值(地址)複製給形參 a,strb 複製給 b。
  2. 方法內 a = b; b = temp; 只是讓局部變量 a、b 指向交換,不影響外部實參 stra、strb。
  3. 方法結束,a、b 銷毀,外部引用不變。

swap(strArr)

  1. 調用時,將 strArr 的引用值複製給形參 t。兩個引用指向同一數組對象。
  2. 方法內 t[0] = t[1]; t[1] = temp; 通過引用訪問數組內部,**修改了數組對象的內容**。
  3. 方法結束,外部 strArr 仍指向同一數組,但內容已變。

核心區別總結

為什麼容易誤解為「傳引用」?

因為「通過傳遞的引用副本,可以修改對象內部狀態」,效果類似 C++ 的傳引用。但本質區別在於:**能否改變實參變量本身的指向**。Java 做不到(無法實現真正的 swap 兩個對象變量)。

實戰建議

  • 若需在方法內「換掉」外部對象,返回新對象讓調用者重新賦值:obj = modify(obj);
  • 集合/數組作為參數時,明確約定:是「只讀」還是「可修改內容」,避免副作用。
  • 不可變對象(String, Integer, LocalDate 等)天然安全,無論傳值/傳引用副本,內容不可變。

總結

Java 只有按值調用。引用類型傳遞的是「引用的值(地址副本)」。理解這一點,能徹底避開參數傳遞相關的邏輯 Bug,也是面試必過的核心知識點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
參數類型傳遞內容方法內能否修改實參指向方法內能否修改對象內容
基本類型值的副本否不適用
引用類型引用的副本(地址值)否(無法讓實參指向新對象)是(通過引用訪問對象內部)