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

Java String 兩種初始化方式的記憶體差異:字串常量池 vs 堆

     編輯:程式設計綜合問答

程式碼對比

String a = "aaa";        // 方式一:字面值
String b = "aaa";        // 指向同一常量池物件
String a1 = new String("aaa"); // 方式二:new 建構式
String b1 = new String("aaa"); // 每次 new 都在堆建立新物件

記憶體模型圖解

特性String s = "aaa"String s = new String("aaa")
儲存區域**字串常量池** (String Constant Pool),屬於方法區/Metaspace**堆** (Heap),受 GC 管理
物件複用相同字面值**共用同一物件每次 new **建立新物件**
生命週期類別卸載前常駐(通常伴隨 JVM 生命週期)無引用時可被 GC 回收
== 比較a == b 為 truea1 == b1 為 false
equals() 比較truetrue (比較內容)

JVM 內部運作

  1. ldc 指令載入常量池字面值,若池中已存在則直接返回引用。
  2. new 指令在堆分配記憶體,呼叫 String(byte[]) 建構式複製字元陣列。
  3. String.intern() 可手動將堆上字串放入常量池(或返回池中現有引用)。

效能與最佳實踐

  • **優先使用字面值** String s = "text":避免不必要的物件建立,利用常量池複用。
  • **僅在需動態構建/頻繁修改時** 使用 new StringBuilder() 或 new String(char[])。
  • **比較內容永遠用 equals()**,除非確定為同一常量池引用才用 ==。
  • JDK 7+ 常量池移至堆,GC 可回收無引用常量,但複用機制不變。

常見面試陷阱

String s1 = "a" + "b";       // 編譯期常量折疊 → "ab" 在常量池
String s2 = "ab";            // s1 == s2 → true
String s3 = new String("a") + new String("b"); // 執行期 new → 堆物件
String s4 = "ab";            // s3 == s4 → false
s3.intern() == s4            // true (JDK 7+)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved