题目
Java中String对象的不可变性及字符串拼接
信息
- 类型:问答
- 难度:⭐
考点
String不可变性,字符串拼接,内存机制
快速回答
String对象在Java中是不可变的,任何修改操作都会创建新对象。字符串拼接的两种主要方式:
- 使用
+运算符:编译期优化常量拼接,运行时创建新对象 - 使用
StringBuilder:适合循环或频繁修改场景,避免内存浪费
1. String不可变性原理
Java中的String类被声明为final,其内部使用private final char[]存储数据。关键特性:
- 字符串一旦创建,内容不可修改
- 任何修改操作(如拼接、替换)都会创建新的String对象
- 通过
hash字段缓存哈希值,提升性能
2. 字符串拼接机制
2.1 使用+运算符
String s1 = "Hello";
String s2 = "World";
String result = s1 + s2; // 创建新对象- 编译期优化:常量拼接(如
"a" + "b")会直接合并为"ab" - 运行时机制:实际编译为
new StringBuilder().append(s1).append(s2).toString()
2.2 使用StringBuilder
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append("World");
String result = sb.toString();- 可变字符序列,避免频繁创建新对象
- 默认容量16字符,自动扩容(2倍+2)
3. 最佳实践
- 单次拼接:直接使用
+运算符(可读性好) - 循环拼接:必须使用StringBuilder,避免内存浪费
// 错误示例:每次循环创建新StringBuilder和String对象
String result = "";
for (int i = 0; i < 100; i++) {
result += i; // 低效!
}
// 正确示例
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {
sb.append(i);
}
String result = sb.toString();4. 常见错误
- 循环中使用
+:导致O(n²)时间复杂度,产生大量临时对象 - 误用StringBuffer:
StringBuilder(非线程安全)比StringBuffer(线程安全)性能更高 - 忽略字符串池:
String s = "a"使用常量池,new String("a")强制创建新对象
5. 扩展知识
- 字符串常量池:JVM维护的字符串缓存,减少重复对象
- intern()方法:手动将字符串加入常量池
- Java 9优化:String内部改用
byte[]存储,节省内存(Latin1字符用1字节,UTF-16用2字节)