String vs StringBuilder vs StringBuffer深度解析

Java 面试核心:String vs StringBuilder vs StringBuffer 深度解析

一、三者核心区别一览

特性 String StringBuilder StringBuffer
可变性 不可变 (Immutable) 可变 (Mutable) 可变 (Mutable)
线程安全 安全(但无关,因为不可变) 不安全 安全(synchronized)
性能 低(每次操作创建新对象) (单线程最快) 中(同步带来开销)
使用场景 字符串常量、少量操作 单线程大量字符串拼接 多线程大量字符串拼接
JDK版本 1.0 1.5 1.0

二、String 的不可变性(Immutable)

为什么不可变?

java 复制代码
// 典型面试代码
String s = "hello";
s = s + " world";  // 创建了新对象,s指向新引用,"hello"被GC

不可变的好处:

  1. 字符串常量池复用 --- 节省内存
  2. HashCode 缓存 --- 适合作为 HashMap 的 Key
  3. 线程安全 --- 天然并发安全
  4. 安全 --- 防止参数被篡改(如网络传输、文件路径)

经典面试题

Q:以下代码创建了几个对象?

java 复制代码
String s1 = new String("abc");

A:2个 --- 堆中的 new String() 对象 + 常量池中的 "abc"
Q:String.intern() 的作用?
A: 将字符串放入常量池,返回常量池引用。用于手动控制字符串复用。


三、StringBuilder vs StringBuffer 源码级对比

1. 线程安全差异(核心考点)

java 复制代码
// StringBuffer:方法加 synchronized
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

// StringBuilder:无同步,裸奔
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

2. 扩容机制(两者相同)

java 复制代码
// 默认初始容量 16,扩容:新容量 = 旧容量 × 2 + 2
void expandCapacity(int minimumCapacity) {
    int newCapacity = value.length * 2 + 2;
    // ...
}

面试建议: 预估长度时用 new StringBuilder(100) 避免频繁扩容。


四、性能对比实测

操作 耗时 说明
String + 循环10000次 很慢 创建大量临时对象
StringBuilder 单线程 最快 无锁,直接操作字符数组
StringBuffer 单线程 较慢 同步锁开销
StringBuffer 多线程 安全 正确性优先

结论: 单线程无脑用 StringBuilder,多线程才考虑 StringBuffer


五、高频面试题精编

Q1:为什么 String 设计成不可变的?

答: 安全(防篡改)、高效(常量池复用)、线程安全、HashCode 缓存。

Q2:+ 操作符底层用什么?

答: JDK8+ 编译器自动转为 StringBuilder.append(),但循环中会每次新建 Builder,应手动用 Builder。

Q3:StringBuilder 为什么快?

答: 1)可变字符数组,原地修改;2)无同步锁开销;3)扩容时批量复制。

Q4:什么场景必须用 StringBuffer?

答: 多线程并发修改同一字符串对象时(实际很少见,通常用并发容器或局部变量)。


六、最佳实践速记

场景 推荐选择
字符串常量、配置项 String
单线程字符串拼接(循环、流处理) StringBuilder
多线程共享可变字符串(罕见) StringBuffer
高并发日志、序列化 StringBuilder(局部变量)

七、总结

String 是不可变的常量,StringBuilder 是单线程的快刀,StringBuffer 是多线程的保险柜。现代 Java 开发,90% 场景用 StringBuilder,剩下 9% 用 String,1% 才用 StringBuffer。


相关推荐
一水21 分钟前
TTFT优化:一个方案的5次推倒重来
java·ai·状态模式
AC赳赳老秦28 分钟前
CSDN 技术社区数据采集:OpenClaw 抓取公开技术热帖,生成领域技术热点周报
java·大数据·前端·数据库·python·php·openclaw
磁爆步兵1 小时前
内存分区:程序运行的核心秘密
java·开发语言·jvm
流星白龙2 小时前
【Docker】4.NameSpace空间隔离实战
java·运维·docker
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题 第207题】【09_Zookeeper篇】第8题:谈谈 ZooKeeper 的可靠性保障机制
java·zookeeper·高可用·可靠性·分布式系统
harmful_sheep2 小时前
maven多版本包导致java.lang.NoClassDefFoundError
java·maven
Mark_ZP2 小时前
【锁2】锁的分类与概念
java·
caishenzhibiao2 小时前
顺势捕猎者副图 同花顺期货通指标
java·c语言·c#
笨蛋不要掉眼泪3 小时前
RabbitMQ消息队列:SpringAMQP
java·分布式·rabbitmq
Mark_ZP3 小时前
【锁6】AQS (AbstractQueuedSynchronizer) 核心原理详解
java