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

Java String 參數傳遞機制深度解析:為什麼方法內修改不影響外部?

     編輯:Java 相關知識

核心結論

Java 只有值傳遞。String 作為不可變物件,在方法中「修改」實際是建立新物件,原參數仍指向舊物件,外部引用不受影響。

實驗驗證

測試 1:直接賦值

public void test() {
    String s = "original";
    change(s);
    System.out.println(s); // 輸出: original
}

public void change(String s) {
    s = s + " changed"; // 建立新 String 物件
    System.out.println(s); // 輸出: original changed
}

測試 2:new String() 建構子

String s = new String("original");
changeNew(s); // 同樣輸出 original

證實:賦值方式 (字面值 vs new) 不影響參數傳遞行為。

測試 3:呼叫方法修改 (concat)

String s = new String("original");
changeByMethod(s); // 同樣輸出 original

public void changeByMethod(String s) {
    s = s.concat(" changed"); // 同樣建立新物件
}

證實:修改手段 (運算子 vs 方法) 不影響結果。

根本原因:String 不可變性與包裝類本質

1. String 內部結構 (JDK 源碼)

public final class String implements Serializable, Comparable {
    private final char[] value; // JDK 8 及之前
    // private final byte[] value; // JDK 9+ Compact Strings
    private final int hash; // 快取 hashCode
    // ...
}
  • final 欄位:初始化後不可變更引用
  • 所有「修改」操作 (concat、replace、substring、+) 皆回傳新 String 實例

2. 類比基本類型包裝類

String 本質上是 char[]/byte[] 的不可變包裝類,行為與 Integer、Long 完全一致:

Integer i = 10;
change(i); // 外部 i 仍為 10

void change(Integer i) {
    i = i + 1; // 自動拆箱、運算、裝箱 → 新 Integer 物件
}

記憶體模型圖解

呼叫前:
main 棧幀: s ──────► 堆: "original" (String 物件)

呼叫 change(s) 後:
main 棧幀: s ──────► 堆: "original" (未變)
change 棧幀: param ─► 堆: "original changed" (新物件)

change 返回,棧幀銷毀:
main 棧幀: s ──────► 堆: "original" (依然指向舊物件)

為什麼設計成不可變?

  1. 字串常量池共享:相同字面值複用同一物件,節省記憶體
  2. 執行緒安全:不可變物件天然無狀態衝突
  3. HashCode 快取:hash 欄位一次計算永久有效,Map Key 高效
  4. 安全性:類載入、檔案路徑、網路參數不可被竄改

正確做法:StringBuilder / StringBuffer

// 高效字串拼接
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) sb.append(i);
String result = sb.toString();

// 多執行緒環境
StringBuffer sbf = new StringBuffer(); // 同步安全

總結對照表

類型傳遞機制方法內修改影響外部典型代表
基本類型值傳遞 (複製位元)否int, double, boolean
物件引用值傳遞 (複製引用)是 (修改物件內部狀態)StringBuilder, List, 自訂類
不可變物件值傳遞 (複製引用)否 (無法修改內部狀態,賦值建立新物件)String, Integer, LocalDate

面試必考點

  1. Java 是值傳遞還是引用傳遞?→ 值傳遞 (引用的值)
  2. String 屬於基本類型嗎?→ 否,是不可變物件
  3. 為什麼 String 設計為不可變?→ 常量池、執行緒安全、HashCode 快取、安全性
  4. 大量字串拼接用什麼?→ StringBuilder (單執行緒) / StringBuffer (多執行緒)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved