首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 參數傳遞本質:String 是值傳遞還是引用傳遞?深度解析

     編輯:程式設計綜合問答

核心結論

Java 只有值傳遞(Pass by Value)。無論基本類型還是引用類型,傳遞的都是「值的副本」。

  • 基本類型:傳遞數值副本
  • 引用類型:傳遞引用的副本(即記憶體地址副本)

代碼驗證

場景 1:重新賦值引用

String a = "123";
void change(String a) {
    a = "234"; // 修改局部引用指向新對象
}
// 調用後:外部 a 仍為 "123"

Person p = new Person("張三");
void change(Person p) {
    p = new Person("李四"); // 修改局部引用
}
// 調用後:外部 p 仍指向 "張三"

String 和自定義對象行為完全一致:都是修改局部變量的引用副本,不影響外部原引用。

場景 2:修改對象內部狀態

StringBuilder sb = new StringBuilder("123");
void modify(StringBuilder sb) {
    sb.append("456"); // 通過引用副本修改同一對象
}
// 調用後:外部 sb 變為 "123456"

Person p = new Person("張三");
void modify(Person p) {
    p.setName("李四"); // 修改對象內部字段
}
// 調用後:外部 p.name 變為 "李四"

這時外部可見變化,因為引用副本指向同一堆內存對象。

String 的特殊性

  • 不可變性:String 無任何修改內部狀態的方法,所有「修改」操作都返回新對象
  • 字面量池:String s = "abc" 可能復用常量池對象
  • 這導致「String 表現得像值類型」,但本質仍是引用類型

對比 C# ref / C++ 引用

語言機制效果
Java值傳遞(引用副本)無法在方法內修改外部引用指向
C# ref真引用傳遞可修改外部引用指向
C++ &引用/別名可修改外部引用指向

JVM 底層視角

方法調用基於棧幀,參數入棧時:

  • 基本類型:直接複製數值
  • 引用類型:複製 32/64 位地址值

C# ref/C++ & 本質是編譯器語法糖,底層同樣傳遞地址,但編譯器生成代碼允許修改調用者棧幀中的變量。

總結

  1. Java 只有值傳遞,無例外
  2. String 無特殊傳遞機制,其「值類型感」源於不可變性
  3. 理解「引用副本」與「對象本體」的區別是關鍵
  4. 面試考點:區分「修改引用」vs「修改對象內容」
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved