第 24 章:String 不可变性
学习目标
- 理解 String 不可变的设计
- 掌握字符串常量池
- 学会 StringBuilder 和字符串拼接优化
一、String 的不可变性
java
String s = "hello";
s = s + " world"; // 看似修改,实际创建了新对象java
public final class String // ① final 类
implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[]; // ② final 字段(Java 8)
// Java 9+: private final byte[] value; (Compact Strings)
}二、字符串常量池
java
String s1 = "hello"; // ① 编译期常量,入池
String s2 = "hello";
System.out.println(s1 == s2); // true(同一个对象)
String s3 = new String("hello");
System.out.println(s1 == s3); // false(new 出来的不入池)
String s4 = s3.intern(); // ② 手动入池
System.out.println(s1 == s4); // true三、String 拼接性能
java
// ❌ 性能差:每次 + 都创建新对象
String result = "";
for (int i = 0; i < 1000; i++) {
result += i; // 1000 次 new String
}
// ✅ 性能好:StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String result = sb.toString();性能差距:1000 次循环时,StringBuilder 比 + 快 100 倍以上。
四、String 常用方法
| 方法 | 作用 |
|---|---|
length() | 长度 |
charAt(i) | 取字符 |
substring(start, end) | 截取 |
indexOf(str) | 查找位置 |
replace(old, new) | 替换 |
split(regex) | 分割 |
trim() | 去首尾空格 |
equals(other) | 比较内容 |
compareTo(other) | 字典序比较 |
isEmpty() | 是否为空 |
contains(str) | 是否包含 |
startsWith(prefix) | 开头匹配 |
toLowerCase() / toUpperCase() | 大小写转换 |
五、Java 9+ Compact Strings
Java 9 改用 byte[] + 编码标志位(LATIN1 / UTF16),节省内存:
java
String s1 = "hello"; // LATIN1,每个字符 1 字节
String s2 = "你好"; // UTF16,每个字符 2 字节六、本章小结
| 要点 | 关键 |
|---|---|
| 不可变 | String 一旦创建不可修改 |
| 常量池 | 字面量入池,new String() 不入池 |
| intern | 手动入池 |
| 拼接优化 | 循环中用 StringBuilder |
动手练习
练习 1:基础题
判断以下输出的结果:
java
String a = "java";
String b = "java";
String c = new String("java");
String d = c.intern();
System.out.println(a == b); // ?
System.out.println(a == c); // ?
System.out.println(a == d); // ?