String a = fuse("a", "");
String b = fuse("a", "");
System.out.println(a == b); // false
String c = "a" + "";
String d = "a" + "";
System.out.println(c == d); // true
String e = fuse("a");
String f = fuse("a");
System.out.println(e == f); // true
String c = "a" + "";
String d = "a" + "";
// 編譯器優化:視為常量表達式
// 編譯時直接計算為 "a"
// 存入字符串常量池
// c 和 d 指向同一個常量池對象
// c == d → true
static String fuse(String t1) { return t1; }
String e = fuse("a");
String f = fuse("a");
// 參數 "a" 是字面量,已在常量池
// 方法直接返回參數引用,無新建對象
// e 和 f 都指向常量池中同一個 "a"
// e == f → true
static String fuse(String t1, String t2) { return t1 + t2; }
String a = fuse("a", "");
String b = fuse("a", "");
// t1 + t2 在運行時執行
// 底層使用 StringBuilder 拼接
// new StringBuilder().append(t1).append(t2).toString()
// toString() 會 new String(char[]) 創建堆上新對象
// 每次調用都創建新對象,地址不同
// a == b → false
| 表達式 | 創建對象數 | 存儲位置 | 備註 |
|---|---|---|---|
"abc" | 0 或 1 | 常量池 | 常量池去重 |
new String("abc") | 1 或 2 | 堆 | 堆上新對象,"abc" 可能在常量池 |
"a" + "b" | 0 或 1 | 常量池 | 編譯期優化為 "ab" |
s1 + s2 (變量) | 1 | 堆 | 運行時 StringBuilder.toString() |
s.intern() | 0 或 1 | 常量池 | 手動入池,返回池中引用 |
byte[] + coder (Compact Strings)"abc".equals(str)String s = "a" + "b"; 優于 String s = "a"; s += "b";三個結果的本質區別在於:編譯期常量折疊 vs 運行時拼接新建對象。字符串常量池是 JVM 優化字符串存儲的關鍵機制,理解其工作原理能寫出更高性能的代碼。