Java String类的基本概念
Java中的String类是用来表示和操作字符串的基础类,它是Java语言中最常用的类之一。String类位于java.lang包中,因此无需额外导入即可直接使用。
String类的不可变性
String对象的一个重要特性是不可变性(immutable)。这意味着一旦String对象被创建,它的值就不能被改变。任何看似修改String的操作,实际上都是创建了一个新的String对象。
String str = "Hello";
str = str + " World"; // 创建了一个新的String对象
这种设计带来几个关键优势:
- 线程安全性:不可变对象天然线程安全
- 缓存哈希值:String的hashCode()可以缓存,提升性能
- 安全性:防止敏感数据被意外修改
String的创建方式
在Java中,创建String对象主要有两种方式:
- 字面量方式:
String str1 = "Java";
- 构造函数方式:
String str2 = new String("Java");
这两种方式在内存分配上有重要区别:
- 字面量方式会检查字符串常量池(String Pool)
- new操作符总是创建新的对象实例
Java String类的核心方法
字符串比较方法
String类提供了多种字符串比较方法:
equals(Object anObject)
:内容比较
String a = "hello";
String b = "HELLO";
a.equals(b); // false
equalsIgnoreCase(String anotherString)
:忽略大小写比较
a.equalsIgnoreCase(b); // true
compareTo(String anotherString)
:字典序比较
"apple".compareTo("banana"); // 负数
字符串查找方法
String类包含多种查找子字符串的方法:
indexOf(int ch)
:查找字符首次出现位置
"hello".indexOf('e'); // 1
lastIndexOf(int ch)
:查找字符最后出现位置contains(CharSequence s)
:检查是否包含子串
字符串操作方法
String类提供了丰富的字符串操作方法:
- 子字符串:
String str = "Hello World";
str.substring(6); // "World"
str.substring(0, 5); // "Hello"
- 连接字符串:
String s1 = "Hello";
String s2 = s1.concat(" Java"); // "Hello Java"
- 替换操作:
"hello".replace('l', 'L'); // "heLLo"
Java String类的性能优化
字符串拼接的优化
在Java中,字符串拼接有多种方式,性能差异显著:
- 使用
+
操作符:
String result = str1 + str2; // 编译后转为StringBuilder
- 使用StringBuilder:
StringBuilder sb = new StringBuilder();
sb.append(str1).append(str2);
String result = sb.toString();
- 使用StringJoiner(Java 8+):
StringJoiner sj = new StringJoiner(",");
sj.add("A").add("B");
String result = sj.toString(); // "A,B"
性能建议:
- 简单拼接使用+
操作符
- 循环拼接使用StringBuilder
- 需要分隔符时使用StringJoiner
字符串常量池的利用
JVM维护了一个字符串常量池(String Pool),合理利用可以节省内存:
- 优先使用字面量而非new String()
- 使用
intern()
方法将字符串加入常量池
String s1 = new String("Java").intern();
String s2 = "Java";
s1 == s2; // true
Java 8+中的String增强功能
String.join()方法
Java 8引入了方便的字符串连接方法:
String joined = String.join(", ", "A", "B", "C"); // "A, B, C"
字符串流操作
结合Stream API处理字符串集合:
List<String> list = Arrays.asList("a", "b", "c");
String result = list.stream().collect(Collectors.joining(","));
多行字符串文本(Java 15+)
Java 15引入了文本块特性,方便处理多行字符串:
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
Java String类的常见问题与解决方案
内存泄漏风险
大字符串处理不当可能导致内存问题:
- 使用
substring()
时注意:
String bigString = ...;
// Java 7前会导致内存泄漏
String small = bigString.substring(0,10);
解决方案:
- 升级到Java 7+
- 显式创建新字符串:new String(bigString.substring(0,10))
编码问题
字符串编码转换常见问题:
// 错误方式
byte[] bytes = str.getBytes(); // 依赖平台默认编码
// 正确方式
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
正则表达式性能
复杂正则可能导致性能问题:
// 预编译正则表达式
Pattern pattern = Pattern.compile("复杂正则");
Matcher matcher = pattern.matcher(input);
最佳实践总结
- 优先使用字符串字面量而非new String()
- 循环拼接使用StringBuilder
- 注意字符串编码,显式指定字符集
- 利用字符串常量池优化内存使用
- 适时使用Java新特性如文本块、StringJoiner等
- 处理大字符串时注意内存,避免substring陷阱
通过深入理解Java String类的这些特性和最佳实践,开发者可以编写出更高效、更健壮的字符串处理代码。