1.String(字符串常量)
- 不可变性:String对象一旦创建,其内容不可修改。每次对字符串的操作(如拼接、替换)都会生成新的String对象,原对象不变。
String s = "Hello"; s = s + " World"; // 生成新对象,原"Hello"对象被丢弃(可能被GC回收)- 内存效率:频繁修改字符串会导致大量临时对象产生,增加内存开销和垃圾回收压力。
- 线程安全:所有方法都是线程安全的(因为不可变)。
- 适用场景:字符串内容不经常变化,或需要共享安全字符串的场景(如配置常量)。
2.StringBuilder(字符串可变,非线程安全)
- 可变性:通过内部字符数组(char[])存储内容,支持原地修改(如append、insert、delete),不会频繁创建新对象。
- 线程安全:非线程安全(方法无synchronized修饰),单线程场景下性能更高。
- 性能:在单线程中频繁修改字符串时,性能远优于String和StringBuffer。
- 初始化:默认容量为16,超出容量时自动扩容(通常翻倍,避免频繁扩容)。
- 适用场景:单线程环境下需要频繁修改字符串的场景(如循环内拼接字符串)。
3.StringBuffer(字符串可变,线程安全)
- 可变性:与StringBuilder类似,支持原地修改。
- 线程安全:线程安全(方法用synchronized修饰),多线程环境下可安全使用,但同步操作会带来性能开销。
- 性能:在多线程中修改字符串时,性能优于String;但在单线程中比StringBuilder慢。
- 初始化:默认容量为16,扩容逻辑与StringBuilder一致。
- 适用场景:多线程环境下需要频繁修改字符串的场景(如线程安全的日志拼接)。
对比总结
| 特性 | String | StringBuilder | StringBuffer |
|---|---|---|---|
| 可变性 | 不可变 | 可变 | 可变 |
| 线程安全 | 安全(不可变) | 非安全 | 安全(synchronized) |
| 性能(单线程) | 低(频繁创建对象) | 最高 | 中(同步开销) |
| 性能(多线程) | 低 | 不安全(需外部同步) | 最高(内置同步) |
| 初始化容量 | 无(内容决定) | 默认16 | 默认16 |
| 扩容机制 | 无(不可变) | 超出容量时自动扩容(翻倍) | 超出容量时自动扩容(翻倍) |
- String:用于只读场景,或字符串内容不频繁修改的情况。
- StringBuilder:单线程中需要频繁修改字符串时(如循环拼接),优先使用。
- StringBuffer:多线程中需要安全修改字符串时(如共享变量拼接),但需注意同步带来的性能损耗。