一、核心概念
1. String的本质
- 不可变性(Immutable):String对象一旦创建,其内容不可更改。所有看似“修改”的操作(如拼接、替换)都会生成新的String对象。
- 存储结构:
- JDK 8及以前:
private final char[] value
。
- JDK 9及以后:
private final byte[] value
+ private final byte coder
(编码标记,节省空间)。
- 字符串常量池:JVM为字符串常量池分配独立内存区域,用于存储字面量创建的String对象(如
String s = "hello"
),避免重复创建相同字符串。
2. 创建方式
方式 |
示例 |
存储位置 |
字面量 |
String s = "hello"; |
常量池 |
构造方法 |
new String("hello"); |
堆内存 |
字符/字节数组 |
new String(char[] data) |
堆内存 |
拼接 |
String s = "he" + "llo"; |
常量池(编译期优化) |
二、操作步骤
1. 创建字符串
// 字面量创建(推荐)
String str1 = "Hello";
// 构造方法创建
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String str2 = new String(chars); // 输出 "Hello"
// 从字节数组创建(需指定编码)
byte[] bytes = {72, 101, 108, 108, 111};
String str3 = new String(bytes, StandardCharsets.UTF_8); // 输出 "Hello"
2. 字符串连接
- 使用
+
操作符(自动调用StringBuilder
):
String result = "Hello, " + "World!"; // 输出 "Hello, World!"
- 使用
concat
方法:
String result = "Hello".concat(" World!"); // 输出 "Hello World!"
3. 字符串比较
4. 获取长度与字符
String str = "Hello";
int length = str.length(); // 5
char firstChar = str.charAt(0); // 'H'
5. 查找与替换
- 查找子串位置:
int index = "Hello World".indexOf("World"); // 6
- 替换子串:
String newStr = "Hello World".replace("World", "Java"); // "Hello Java"
6. 截取与拆分
- 截取子串:
String sub = "Hello World".substring(6); // "World"
- 按正则拆分:
String[] parts = "apple,banana,orange".split(","); // ["apple", "banana", "orange"]
7. 格式化字符串
String formatted = String.format("Number: %d, Text: %s", 123, "Java");
// 输出 "Number: 123, Text: Java"
三、常见错误与注意事项
1. 常见错误
2. 注意事项
四、使用技巧
1. 快速判断字符串
2. 大小写转换
String upper = "hello".toUpperCase(); // "HELLO"
String lower = "HELLO".toLowerCase(); // "hello"
3. 去除空格与修剪
String trimmed = " Java ".trim(); // "Java"
五、最佳实践与性能优化
1. 频繁修改用StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String result = sb.toString(); // 单次生成最终字符串
2. 避免重复创建对象
// 不推荐
String s1 = "Hello" + " " + "World";
String s2 = "Hello " + "World";
// 推荐(合并常量)
String s = "Hello World";
3. 缓存哈希值(适用于自定义类)
- 若将String作为
HashMap
的Key,其hashCode
会被缓存,提升性能。
4. 使用String.valueOf()
转换类型
int num = 123;
String str = String.valueOf(num); // "123"
六、性能对比
操作 |
String |
StringBuilder |
单次拼接 |
✅ |
✅ |
多次拼接(1000次) |
❌(性能差) |
✅(高效) |
七、总结
- 优先使用字面量创建字符串,利用常量池优化。
- 避免使用
==
比较内容,改用equals()
。
- 频繁修改字符串时使用
StringBuilder
,减少对象创建。
- 理解不可变性,避免误以为直接修改原字符串。