String 對象一旦創建,其內部 char[] value 數組永不改變。所謂「修改」實為創建新對象,引用指向新內存地址。
String s1 = "慕課網";
s1 = "歡迎來到:" + s1; // 實際過程:
// 1. 創建 StringBuilder
// 2. append("歡迎來到:")
// 3. append(s1)
// 4. toString() 產生新字符串對象
// 5. s1 引用指向新對象,原 "慕課網" 對象若無其他引用將被 GC
| 創建方式 | 存儲位置 | 同內容多次創建 |
|---|---|---|
String s = "abc" | 常量池 | 同一對象(編譯器優化) |
new String("abc") | 堆內存 | 每次新對象 |
"a" + "b" (編譯期常量) | 常量池 | 優化為 "ab" |
"a" + s (含變量) | 堆內存 | 運行時新對象 |
String s1 = "imooc", s2 = "imooc"; String s3 = "I love" + s1; // 運行時拼接 → 堆 String s4 = "I love " + s1; // 同上 System.out.println(s1 == s2); // true (常量池同一引用) System.out.println(s1 == s3); // false (堆 vs 常量池) System.out.println(s3 == s4); // false (兩次獨立運行時拼接)
charAt(int index):返回指定索引字符indexOf(String str):首次出現索引,無則 -1startsWith/endsWith:前綴/後綴匹配equals(Object o):內容比較(必須用此而非 ==)equalsIgnoreCase:忽略大小寫比較toLowerCase()/toUpperCase():返回新字符串trim():移除首尾空白字符(含 \t \n \r)substring(int begin, int end):含頭不含尾,[begin, end)replace(char old, char new) / replace(CharSequence, CharSequence):全量替換replaceAll(String regex, String replacement):正則替換split(String regex):正則分割返回數組,尾部空串默認丟棄,需 split(regex, -1) 保留valueOf(primitive):基本類型 → String,等同 String.valueOf()toCharArray():轉字符數組(拷貝)getBytes(Charset):編碼為字節數組,指定編碼避免亂碼+= 會產生大量臨時對象,導致 GC 壓力;== 比較引用地址,極易產生邏輯 Bug;split("\\|")、split("\\.");str.getBytes(StandardCharsets.UTF_8)。操作 相對耗時 (百萬次循環) String += 12000 ms StringBuilder.append 5 ms StringBuffer.append 8 ms (線程安全開銷)