String 是 Java 使用率最高的類型,也是面試與開發中坑最多的區域。本文精選 10 個高頻問題,從底層原理到實戰技巧,助你徹底掌握字符串核心竅門。
==:比較引用地址(是否同一對象)equals():比較字符序列內容(值相等性)equals()Objects.equals(a, b) 空安全,推薦 JDK 7+String 不可變:創建後內容常駐堆/常量池,直到 GC 回收,內存快照可被讀取char[] 可變:用完後可手動清零 Arrays.fill(arr, '\0'),縮短敏感數據暴露窗口Console.readPassword() 返回 char[])switch(str.toLowerCase()) { case "a": ... }int/enum/byte/short/charhashCode() + equals() 兩階段判斷int n = Integer.parseInt("10"); // 基礎
int n = Integer.parseInt("FF", 16); // 指定基數(16進制)
// 異常處理:NumberFormatException
String[] parts = str.split("\\s+"); // 正則:一個或多個空白字符(空格、制表、換行)
| 版本 | 實現 | 風險 | 對策 |
|---|---|---|---|
| JDK 6 | 共享底層 char[],只存 offset/count |
長字符串 substring(0,1) 導致大數組無法 GC |
new String(str.substring(...)) 強制複製 |
| JDK 7+ | 複製新 char[] |
無洩漏,但微增內存/CPU | 無需特殊處理 |
| 類 | 可變性 | 線程安全 | 性能 | 適用場景 |
|---|---|---|---|---|
| String | 不可變 | 是(不可變天然安全) | 拼接慢 | 常量、鍵值、少量拼接 |
| StringBuilder | 可變 | 否 | 最快 | 單線程大量拼接(推薦) |
| StringBuffer | 可變 | 是(同步鎖) | 較慢 | 多線程共享緩衝區(罕見) |
編譯器優化:s = "a" + "b" + "c" 編譯期常量折疊 → "abc";變量拼接自動用 StringBuilder。
// Java 11+
String repeated = "abcd".repeat(3); // "abcdabcdabcd"
// Java 8/9/10:Apache Commons Lang
String repeated = StringUtils.repeat("abcd", 3);
// 手工實現
String repeated = new String(new char[3]).replace("\0", "abcd");
String str = "Sep 17, 2013";
Date date = new SimpleDateFormat("MMMM d, yy", Locale.ENGLISH).parse(str);
// 輸出:Tue Sep 17 00:00:00 EDT 2013
// Java 8+ 推薦:DateTimeFormatter + LocalDate
LocalDate date = LocalDate.parse("2013-09-17", DateTimeFormatter.ISO_LOCAL_DATE);
// Apache Commons Lang
int count = StringUtils.countMatches("11112222", "1"); // 4
// Java 8 Stream
long count = "11112222".chars().filter(c -> c == '1').count();
// 手工循環(最高性能)
int count = 0;
for (char c : str.toCharArray()) if (c == '1') count++;
// 方法 1:正則
boolean allUpper = str.matches("[A-Z]+");
// 方法 2:逐字符檢查(性能最優)
boolean allUpper = true;
for (char c : str.toCharArray()) {
if (!Character.isUpperCase(c)) { allUpper = false; break; }
}
// 方法 3:Apache Commons
boolean allUpper = StringUtils.isAllUpperCase(str);
equals(),Objects.equals() 防空指針char[],用後即清零StringBuilder,避免循環 +substring 洩漏,放心使用DateTimeFormatter(線程安全、不可變)StringUtils(Apache)或 Strings(Guava)Pattern.compile() 復用,避免重複編譯字符串看似簡單,實則暗藏大學問。精通這 10 大問題,能讓你在代碼質量、性能優化、安全防護上更上一層樓。