Java字符处理之char、String、StringBuilder和StringBuffer详解
作者:普通网友
这篇文章主要介绍了Java字符处理之char、String、StringBuilder和StringBuffer的相关资料,它们各自有着独特的特性和适用场景,文中通过代码介绍的非常详细,需要的朋友可以参考下
好的,我们来深入解析 Java 中的 char、String、StringBuilder 和 StringBuffer。理解它们之间的区别对于编写高效、正确的 Java 代码至关重要。
1.char:基本数据类型
- 本质:
char是 Java 中的基本数据类型(Primitive Type),表示一个 16 位无符号 Unicode 字符。它占用 2 个字节(16 位)内存空间。 - 值范围:最小值为
\u0000(即 0),最大值为\uffff(即 65, 535)。可以表示世界上大多数字符。 - 特点:
- 是基本类型,不是对象,没有方法。
- 字面值用单引号
'表示,例如:char grade = 'A'; - 可以直接参与算术运算(提升为
int)。 - 存储在栈内存(如果作为局部变量)或对象内部。
- 用途:主要用于表示单个字符。
2.String:不可变的字符序列
- 本质:
String是一个 类(Class),用于表示不可变的字符序列。它内部封装了一个char[]数组来存储字符。 - 核心特性 - 不可变性 (Immutability):
- 一旦
String对象被创建,其包含的字符序列 就不能被更改。任何看似修改String的操作(如concat,substring,toUpperCase,replace等),实际上都是 创建并返回一个全新的String对象。 - 优点:
- 线程安全:由于不可变,多个线程可以安全地共享同一个
String对象,无需同步。 - 缓存与优化:Java 使用“字符串常量池”(String Pool)来缓存字符串字面量,减少重复创建的开销。例如:
String s1 = "hello"; // 可能从池中获取 String s2 = "hello"; // 指向池中同一个对象 String s3 = new String("hello"); // 强制在堆上创建新对象 - 安全性:常用于敏感信息(如密码)的传递,因为不可变,避免了内容被意外修改的风险。
- HashCode 稳定性:
String的hashCode()值在对象创建时计算一次并缓存,后续调用直接返回缓存值,效率高且稳定,非常适合作为哈希表的键(如HashMap)。
- 线程安全:由于不可变,多个线程可以安全地共享同一个
- 缺点:
- 频繁修改效率低:每次“修改”都会产生新的对象,如果在一个循环中反复拼接字符串,会产生大量中间临时对象,增加 GC 压力。
- 一旦
- 创建方式:
- 字面量:
String s = "abc";(优先使用常量池) - 构造函数:
String s = new String("abc");(在堆上新建对象) - 字符数组:
char[] data = {'a', 'b', 'c'}; String str = new String(data); +运算符拼接(底层可能编译优化为StringBuilder)。
- 字面量:
- 常用方法:
length(),charAt(int index),concat(String str),equals(Object anObject),indexOf(String str),substring(int beginIndex),toLowerCase(),toUpperCase(),trim(),split(String regex)等。
3.StringBuilder:可变的字符序列 (非线程安全)
- 本质:
StringBuilder也是一个类,用于表示 可变的字符序列。它也封装了一个char[]数组(称为缓冲区)。 - 核心特性 - 可变性 (Mutability):
- 对象内部的字符序列 可以被修改。修改操作(如
append,insert,delete,replace)直接在原有缓冲区上进行,不会创建新对象(除非缓冲区容量不足需要扩容)。
- 对象内部的字符序列 可以被修改。修改操作(如
- 特点:
- 高效修改:非常适合在循环中或需要多次修改字符串内容的场景(如日志拼接、动态 SQL 生成),避免了
String拼接带来的性能问题。 - 非线程安全:
StringBuilder的方法 没有 进行同步(synchronized)处理。如果多个线程同时修改同一个StringBuilder实例,可能会导致数据不一致。因此,它适用于 单线程环境。 - 创建:通常通过构造函数
new StringBuilder()或new StringBuilder(String str)创建。 - 最终字符串获取:通过
toString()方法获取最终的不可变String对象。
- 高效修改:非常适合在循环中或需要多次修改字符串内容的场景(如日志拼接、动态 SQL 生成),避免了
- 常用方法:
append(...)(多种重载,支持基本类型、对象等),insert(int offset, ...),delete(int start, int end),replace(int start, int end, String str),reverse(),setCharAt(int index, char ch),toString()。
4.StringBuffer:可变的字符序列 (线程安全)
- 本质:
StringBuffer是StringBuilder的 线程安全版本。它也用于表示可变的字符序列。 - 核心特性 - 可变性与线程安全:
- 对象内部的字符序列可以被修改。
- 所有对
StringBuffer进行修改的公共方法(如append,insert,delete,replace)都使用了synchronized关键字进行同步,保证了在 多线程环境 下的操作安全。
- 特点:
- 线程安全:可以在多线程环境下安全地修改同一个
StringBuffer实例。 - 性能开销:由于同步锁的存在,
StringBuffer的操作性能通常 低于StringBuilder。在单线程环境中使用StringBuffer会带来不必要的性能损失。 - 创建与获取:用法与
StringBuilder类似,通过构造函数创建,通过toString()获取最终String。
- 线程安全:可以在多线程环境下安全地修改同一个
- 历史:
StringBuffer是 JDK 1.0 就存在的类。StringBuilder是在 JDK 1.5 引入的,作为StringBuffer的非线程安全替代品,旨在提高单线程下的性能。
总结对比表
| 特性 | char | String | StringBuilder | StringBuffer |
|---|---|---|---|---|
| 类型 | 基本数据类型 | 类 (不可变) | 类 (可变) | 类 (可变) |
| 可变性 | 值可变 | 不可变 | 可变 | 可变 |
| 线程安全 | 不适用 (基本类型) | 是 (因不可变) | 否 | 是 (同步方法) |
| 性能 (修改) | 高 | 低 (创建新对象) | 高 (单线程) | 中低 (因同步) |
| 适用场景 | 单个字符 | 常量字符串、键值、方法参数传递等 | 单线程下频繁修改字符串 | 多线程下频繁修改字符串 |
| 创建方式 | 字面量 'A' | 字面量 "abc" / new String(...) | new StringBuilder() | new StringBuffer() |
| 最终字符串 | - | 自身 | toString() | toString() |
选用建议
- 单个字符:使用
char。 - 不常修改的字符串:优先使用
String(利用常量池、线程安全、HashCode 稳定等优点)。 - 单线程下频繁修改字符串:强烈推荐使用
StringBuilder(性能最优)。 - 多线程下频繁修改字符串:使用
StringBuffer(保证线程安全)。 - 简单拼接:少量固定字符串拼接可用
String的+(编译器可能会优化成StringBuilder)。大量或循环拼接务必使用StringBuilder/StringBuffer。
理解它们的设计意图和优缺点,有助于你在不同场景下做出最合适的选择,写出更高效、更健壮的 Java 代码。
总结
到此这篇关于Java字符处理之char、String、StringBuilder和StringBuffer的文章就介绍到这了,更多相关Java字符处理char、String与StringBuilder内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
