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

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

     編輯:Java 相關知識

核心結論

Java 只有值傳遞 (Pass by Value)。無論基本類型還是引用類型,方法調用時都是將實參的值的副本傳給形參。區別在於:

  • 基本類型:副本是字面值本身
  • 引用類型:副本是引用值 (對象地址)

基本類型:值傳遞無歧義

public static void test(boolean flag) {
    flag = !flag; // 修改副本
    System.out.println("方法內: " + flag); // false
}
public static void main(String[] args) {
    boolean flag = true;
    System.out.println("調用前: " + flag); // true
    test(flag);
    System.out.println("調用後: " + flag); // true,原值未變
}

引用類型:傳遞的是「引用的值」

什麼是引用?

引用是指向堆中對象的「地址句柄」,佔用棧內存。多個引用可指向同一對象:

StringBuffer a = new StringBuffer("Hello");
StringBuffer b = a; // b 複製了 a 的引用值 (地址)
b.append(", World");
System.out.println(a); // Hello, World — 同一對象被修改

兩個經典案例揭示本質

案例一:修改對象內部狀態 — 可見變化

public static void test(StringBuffer sb) {
    sb.append(", World!"); // 通過引用副本找到原對象,修改內容
}
public static void main(String[] args) {
    StringBuffer s = new StringBuffer("Hello");
    test(s);
    System.out.println(s); // Hello, World! — 原對象被改變
}

誤以為是引用傳遞:實際是引用值副本指向同一對象,通過副本操作對象內部狀態。

案例二:重新賦值引用 — 原引用不變

public static void test(String str) {
    str = "World"; // 修改形參引用指向新對象
}
public static void main(String[] args) {
    String s = "Hello";
    test(s);
    System.out.println(s); // Hello — 原引用仍指向 "Hello"
}

證明是值傳遞:形參 str 是實參 s 的引用副本,str = "World" 只是讓副本指向新對象,不影響原引用 s。

為什麼會有「引用傳遞」的誤解?

源於 C/C++ 程序員類比 指針傳遞:

C/C++Java
值傳遞:無法修改原值值傳遞:基本類型同理
指針傳遞:可通過指針修改原值引用值傳遞:可通過引用修改對象內部狀態
指針可算術運算、直接訪問內存引用不可運算、不暴露地址、GC 管理

Java 設計者有意移除指針,保留引用,簡化內存管理,但參數傳遞機制本質未變:始終傳遞值的副本。

實戰判斷口訣

  1. 方法內 賦值 (=) 形參 → 不影響 實參 (基本類型、引用類型同理)
  2. 方法內 調用方法/修改字段 形參指向的對象 → 影響 實參指向的同一對象
  3. 需修改實參引用指向?無法直接實現,可返回新對象或包裝在容器/數組/Holder 中

總結

Java 參數傳遞統一為值傳遞。理解「引用值」是地址副本,而非對象本身,是避免 Bug、設計清晰 API 的關鍵。

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