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

Java String 對象創建機制:字面量池、編譯期優化與 new String() 區別

     編輯:程式設計綜合問答

經典面試題:String s = "abc"; String s1 = "a"+"b"+"c"; 創建了幾個對象?答案取決於**編譯期常量折疊**與**運行時字符串常量池**機制。

場景一:字面量拼接 (編譯期常量)


String s = "abc";
String s1 = "a" + "b" + "c"; // 編譯期常量折疊 → "abc"
  • 創建對象數:1 個 (String 實例 "abc" 在常量池)。
  • 原因: "a"+"b"+"c" 全為編譯期常量,`javac` 編譯時直接優化為 "abc" 字節碼(查看 javap -c 可見 ldc "abc")。運行時僅從常量池加載同一引用,s == s1 為 true。

場景二:變量參與拼接 (運行時新建)


String a = "abc";
String c = a + "d"; // 運行時 new StringBuilder().append(a).append("d").toString()
String d = a + "d"; // 另一次新建
  • 創建對象數:3 個 (a 常量池 "abc"、c 堆上新 String、d 堆上另一新 String)。
  • 原因: 含變量 a 的拼接無法編譯期確定,運行時通過 StringBuilder 生成新 String 對象(Java 9+ 可能用 invokedynamic 優化,但語義仍為新建)。
  • c == d 為 false (不同堆對象),c.equals(d) 為 true (內容相同)。

核心原則總結

表達式對象創建位置備註
"literal"字符串常量池 (元空間)類加載時創建/復用
"a"+"b" (全常量)常量池 (編譯期折疊)等價於 "ab"
new String("abc")堆內存強制新建,**極少必要**
var + "str"堆內存運行時 StringBuilder 生成
str.intern()常量池 (可能新增)手動入池,慎用

工程建議

  • 優先使用字面量 "...",避免 new String()。
  • 拼接循環/大量字符串用 StringBuilder 顯式控制,避免隱式創建大量臨時對象。
  • 比較內容**永遠用 equals()**,除非確定雙方均為常量池引用(如枚舉、常量定義)。
  • 深入理解請閱讀《深入理解 Java 虛擬機器》第 3 章《垃圾收集器與內存分配策略》中常量池演進歷史 (JDK 1.6 永久代 → 1.7/1.8 元空間)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved