Java String 類完全指南:建立、常用方法、格式化與記憶體機制
字串在 Java 中屬於物件,java.lang.String 類別提供豐富操作方法。String 物件不可變——一旦建立,值無法改變。頻繁修改請用 StringBuilder。
建立字串的方式
字面值(常量池)
String greeting = "菜鳥教程"; // 編譯器自動建立 String 物件
建構子(堆疊新物件)
char[] arr = {'r','u','n','o','o','b'};
String s = new String(arr); // "runoob"
// 其他常用建構子:
// new String(byte[], charset)
// new String(StringBuffer)
// new String(StringBuilder)
關鍵差異: "abc" 可能複用常量池物件;new String("abc") 強制在堆疊建立新物件。比較內容請用 equals(),勿用 ==。
字串長度
String site = "www.runoob.com";
int len = site.length(); // 14
字串連接
concat():s1.concat(s2) 返回新字串。
+ 操作符:編譯器優化為 StringBuilder.append(),最常用。
"Hello" + " " + "Runoob" + "!" // "Hello Runoob!"
格式化字串
String.format() 返回格式化後的 String(而非輸出),可復用:
String fs = String.format("浮點數:%f, 整數:%d, 字串:%s", 3.14, 42, "test");
System.out.println(fs); // 浮點數:3.140000, 整數:42, 字串:test
String 核心方法分類速查
查詢與比較
| 方法 | 說明 |
charAt(index) | 指定索引字元 |
compareTo(str) | 字典序比較 |
compareToIgnoreCase(str) | 忽略大小寫比較 |
equals(obj) / equalsIgnoreCase(str) | 內容相等判斷 |
startsWith(prefix) / endsWith(suffix) | 前綴/後綴檢查 |
contains(s) | 是否包含子字串 (JDK 1.5+) |
indexOf(ch/str) / lastIndexOf(ch/str) | 搜尋索引 |
matches(regex) | 正則全匹配 |
擷取與轉換
| 方法 | 說明 |
substring(begin) / substring(begin, end) | 子字串 [begin, end) |
toUpperCase() / toLowerCase() | 大小寫轉換 |
trim() | 移除首尾空白 |
replace(old, new) / replaceAll(regex, repl) / replaceFirst(regex, repl) | 替換 |
split(regex) / split(regex, limit) | 分割為陣列 |
toCharArray() | 轉字元陣列 |
getBytes(charset) | 編碼為位元組陣列 |
靜態工廠方法
| 方法 | 說明 |
valueOf(primitive/Object) | 各型別轉字串 |
copyValueOf(char[]) | 字元陣列轉字串 |
format(format, args) | 格式化 |
join(delimiter, elements) | 連接 (JDK 1.8+) |
記憶體模型:字串常量池
- 字面值: 編譯期確定,存放於字串常量池(JDK 7 起移至堆疊),相同內容共享同一物件。
- new String(): 執行期在堆疊建立新物件,不進常量池(除非呼叫
intern())。
intern():若常量池已有相同內容,返回池中引用;否則將此物件加入池並返回引用。
經典面試題
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc").intern();
System.out.println(s1 == s2); // true(常量池共享)
System.out.println(s1 == s3); // false(堆疊新物件)
System.out.println(s1 == s4); // true(intern 返回池中引用)
System.out.println(s3 == s4); // false
效能建議
- 大量拼接用
StringBuilder。
- 比較內容用
equals(),避免 ==。
- 頻繁
split()、replaceAll() 涉及正則編譯開銷,熱點路徑預編譯 Pattern。
- 指定編碼用
getBytes(StandardCharsets.UTF_8) 避免平台預設編碼差異。