Java 中 String 為 final 類,底層 char[]/byte[] (Java 9+) 不可變。所有「修改」操作實際產生新物件,這是效能分析的基石。
// ❌ 循環中使用 + 號,產生大量中間物件
String s = "";
for (int i = 0; i < 1000; i++) s += i;
// ✅ 使用 StringBuilder (單執行緒) 或 StringBuffer (多執行緒)
StringBuilder sb = new StringBuilder(1000 * 4); // 預估容量避免擴容
for (int i = 0; i < 1000; i++) sb.append(i);
String result = sb.toString();
// 正則分割 (編譯 Pattern 可複用)
Pattern pattern = Pattern.compile("\\|");
String[] parts = pattern.split("a|b|c");
// 簡單分隔符用 String.split 即可 (內部已優化)
String[] items = "apple,banana,orange".split(",");
// 佔位符格式化 (效能優於 + 號)
String sql = String.format("SELECT * FROM %s WHERE id = %d AND name = '%s'", "user", 1001, "張三");
// Java 15+ 文本塊 (多行 SQL/JSON/HTML)
String json = """
{
"name": "%s",
"age": %d
}
""".formatted("李四", 25);
// Apache Commons Lang (推薦)
StringUtils.isBlank(str); // null、""、" " 均判 true
StringUtils.isNotBlank(str);
// 原生 JDK 11+
str.isBlank(); // 僅檢查空白字元,不含 null 安全
// 包含檢查
"Hello World".contains("World"); // true
// 正則替換 (預編譯 Pattern)
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("订单123金额456");
String replaced = m.replaceAll("#"); // "订单#金额#"
// 字面量替換 (無正則開銷)
"a-b-c".replace("-", "|"); // "a|b|c"
"a-b-c".replaceAll("-", "|"); // 同 replace,但支援正則
| 場景 | 陷阱 | 優化 |
|---|---|---|
| 大量拼接 | 循環 + 號 / String.concat | StringBuilder 預分配容量 |
| 頻繁 split | 重複編譯正則 | Pattern.compile 靜態複用 |
| subString 共享陣列 (Java 7-) | 長字串截取短子串導致記憶體洩漏 | new String(str.substring(...)) 強制複製 / 升級 JDK 8+ |
| 字串池濫用 | 大量 intern() 導致 PermGen/Metaspace OOM | 僅對高重複率業務鍵值使用 |
String.strip()、stripLeading()、stripTrailing():Unicode 感知去空白String.repeat(int)、lines()、indent(int):常用工具方法內建掌握字串不可變本質,選對工具類(StringBuilder/Pattern/StringUtils),善用新版本 API,即可寫出高效、可讀的字串處理代碼。