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

深入理解 Java String:物件創建機制、常量池、編譯器優化與不可變性本質

     編輯:Java 程式設計入門

一、字面值 vs new String():物件創建真相

核心結論


String s = new String("abc");  // 創建 2 個 String 物件
  1. 常量池:編譯期將字面值 "abc" 放入常量池(.class 檔常量表 → 運行時常量池)
  2. 堆:運行期 new String() 複製常量池內容到堆建立新物件

驗證代碼


String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);  // true:同一常量池物件

String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3 == s4);  // false:兩個堆物件
System.out.println(s3.equals(s4));  // true:內容相同

延伸:String s1 = new String("abc"); String s2 = new String("abc"); 創建幾個物件?

三個:常量池 1 個 + 堆 2 個。

二、字串連接與轉換的編譯器優化

JLS 規範核心

  • 字串轉換環境:僅雙元 + 其中一操作數為 String
  • 串接運算:另一操作數運行期轉 String,基本型態視為包裝類 → toString()
  • 優化許可:編譯器可使用 StringBuilder 替換連續串接

案例分析:str = 1+2+str+3+4;


// 運行期等價於(編譯器優化後):
str = new StringBuilder()
        .append(1+2)      // 常量折疊:3
        .append(str)
        .append(3)
        .append(4)
        .toString();
// 創建物件:1 StringBuilder + 1 String 結果 + 可能 "3"/"4" 常量池物件

特殊案例:純字面值連接


String s1 = "3jf34";
String s2 = "3" + "jf" + "3" + "4";
System.out.println(s1 == s2);  // true:編譯期常量折疊,同一常量池物件

JLS 15.28:常量表達式編譯期計算,視為字面值。

三、String 不可變性本質

不可變意味著什麼?

  • 物件內容不可變:任何「修改」操作返回新物件
  • 引用變數可變:str = str + "x" 是引用指向新物件,舊物件未變

為什麼設計為不可變?

  1. 常量池共享:相同內容單一物件,節省記憶體
  2. 執行緒安全:不可變物件天然無狀態衝突
  3. 安全性:類載入器、網路連線、檔案路徑等敏感參數不可被竄改
  4. HashCode 快取:hashCode() 計算一次永久有效,Map 鍵高效
  5. Demeter 法則:OOD 原則建議盡可能設計為不可變類

四、常見面試陷阱總結

代碼物件數解析
String s = "a" + "b" + "c";1編譯期常量折疊
String s = new String("abc");2常量池 + 堆
String s = new String("a") + new String("b");42常量池 + 2堆 + 1結果(含Builder)
String s = "ab"; String t = "a" + "b";1常量折疊同一物件
String s = "a"; String t = s + "b";2運行期 Builder 建立新物件

五、實戰建議

  1. 優先使用字面值 String s = "text"; 而非 new String("text")
  2. 循環/大量拼接 必須 使用 StringBuilder
  3. 方法參數/返回值使用 String 而非 StringBuilder(API 穩定性)
  4. 理解 == 比較引用,equals() 比較內容,intern() 手動入池
  5. 避免 String.intern() 濫用(永久代/Metaspace 壓力)

結語

掌握 String 物件創建機制、常量池與堆的交互、編譯器優化邊界、不可變性設計哲學,是寫出正確、高效 Java 代碼的基石。String 看似簡單,實則蘊含 JVM 核心記憶體管理智慧。

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