字符串本質是 char[],但 Java 中雙引號聲明的字符串都是 String 對象,體現「一切皆對象」。String 為 final 類,不可變:任何修改操作都會創建新對象。
| 特性 | String | StringBuilder | StringBuffer |
|---|---|---|---|
| 可變性 | 不可變 | 可變 | 可變 |
| 線程安全 | 是 (不可變天然安全) | 否 | 是 (方法 synchronized) |
| 性能 | 拼接慢 (創建新對象) | 最快 (單線程推薦) | 稍慢 (同步開銷) |
| 適用場景 | 常量、少量拼接 | 大量拼接、單線程 | 多線程共享字符串緩衝區 |
class StringTest {
public static void main(String[] args) {
String constStr = "";
long t = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) constStr += i;
System.out.println("String: " + (System.currentTimeMillis() - t) + "ms"); // ~300ms
StringBuilder sb = new StringBuilder();
t = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) sb.append(i);
System.out.println("StringBuilder: " + (System.currentTimeMillis() - t) + "ms"); // ~1ms
}
}
結論:大量拼接必須用 StringBuilder (單線程) 或 StringBuffer (多線程)。
JVM 維護一個字符串常量池。雙引號字面量或 intern() 會檢查池中是否存在相同字符串,存在則返回引用,否則創建並入池。
String s1 = "Hello";
String s2 = "Hello"; // 同一對象
String s3 = new String("Hello"); // 堆上新對象
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s1.equals(s3)); // true
new String("Hello") 至少創建 2 個對象:池中 "Hello" + 堆上新對象。
equals(Object):內容比較(必須用此)。equalsIgnoreCase(String):忽略大小寫。compareTo(String):字典序比較 (實現 Comparable)。==:引用比較(勿用於內容比較)。indexOf(str/char, fromIndex) / lastIndexOf:返回索引,-1 表未找到。contains(CharSequence):是否包含子串。startsWith/endsWith(prefix/suffix):前綴/後綴匹配。substring(begin, end):提取子串 [begin, end)。JDK 7+ 會複製字符數組,不再共享。charAt(index):單字符訪問。split(regex, limit):正則分割。split("\\s+") 按空白字符分割。replace(oldChar, newChar) / replace(CharSequence, CharSequence):字面量替換。replaceAll/replaceFirst(regex, replacement):正則替換。String.format(fmt, args) / String.format(locale, fmt, args):C 風格格式化。valueOf(primitive/object):基本類型/對象轉字符串。toCharArray() / getBytes(charset):轉字符/字節數組。trim() / strip() (JDK 11+):去除首尾空白。
public static void main(String[] args) { // args[0] 為第一個參數,不含程序名
for (String arg : args) System.out.println(arg);
}
// 執行: java MyClass Hello World
// 輸出: Hello / World
// 匹配 Email 簡易版
String emailRegex = "^[\\w.-]+@[\\w.-]+\\.\\w+$";
boolean valid = "test@example.com".matches(emailRegex); // true
// 使用 Pattern/Matcher 復用編譯
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("abc123def456");
while (m.find()) System.out.println(m.group()); // 123, 456
StringBuilder (單線程) / StringBuffer (多線程)。equals()。new String()(利用常量池)。substring 或 split 創建大量臨時對象,可預編譯 Pattern。strip(), isBlank(), lines() 等新方法。