問題:String str = "abc"; 與 String str1 = new String("abc"); 在記憶體中有何不同?
String str = "abc";
│
▼
┌─────────────────────┐
│ String Constant Pool (常量池) │
│ "abc" ◄─────────────┤ (單一實例,JVM 保證唯一)
└─────────────────────┘
String str1 = new String("abc");
│
▼
┌─────────────────────┐ ┌─────────────────────┐
│ Heap (堆) │ │ String Constant Pool │
│ String Object │ │ "abc" (常量池已有) │
│ value: "abc" │ └─────────────────────┘
│ ref: str1 ─────────┘
└─────────────────────┘
| 寫法 | 建立物件數 | 儲存位置 | 指向 |
|---|---|---|---|
String s = "abc"; | 0 或 1(常量池已有則複用) | 常量池 | 常量池實例 |
new String("abc") | 1(堆上新建)+ 常量池可能有 1 個 | 堆 | 堆上新物件 |
String s2 = new String("abc").intern(); // 將堆上物件內容登錄至常量池,返回常量池引用
// s2 == "abc" 為 true
intern():若常量池已有相同內容字串,返回該引用;否則將此字串加入常量池並返回引用。intern() 行為略有調整,但語意一致。"abc",享受常量池複用與 == 比較優勢。StringBuilder/StringBuffer。new String()(如刻意建立不同物件給 synchronized 鎖用)。理解常量池機制,能避免記憶體浪費與錯誤的 == 比較。