Java字符串详解:String、StringBuffer、StringBuilder 区别、原理与实战场景

📅 2026/7/16 12:04:48
Java字符串详解:String、StringBuffer、StringBuilder 区别、原理与实战场景
在 Java 开发面试中String、StringBuffer、StringBuilder 的区别是经典必考原题。三者都是用于存储和操作字符串但在可变性、线程安全、执行效率、底层存储、扩容机制上完全不同。很多新手开发无脑使用 String 做字符串拼接导致频繁创建新对象、程序性能极低或分不清线程安全场景线上出现并发错乱问题。本文基于标准面试答案完整拆解三者底层原理、核心差异、代码实战、性能对比、业务选型一次性彻底吃透字符串体系。一、三者核心总览面试一句话背诵String字符串不可变每次修改都会生成新对象效率低线程安全StringBuffer字符串可变方法带 synchronized 锁线程安全、效率较低适用于多线程拼接场景StringBuilder字符串可变无锁线程不安全、效率最高适用于单线程拼接场景。二、底层原理深度解析2.1 String 不可变原理JDK8 及以前String 底层是private final char[] valueJDK9 及以后优化为private final byte[] value。final 修饰数组引用意味着数组地址不可修改且 String 没有提供任何修改数组内容的公开方法。所以String 一旦创建内容永久不可变。任何拼接、截取、替换操作都不会修改原字符串而是新建一个字符串对象。2.2 StringBuffer / StringBuilder 可变原理二者全部继承自AbstractStringBuilder底层是可变 char[] 数组没有 final 修饰。支持动态扩容、原地修改字符内容不会频繁创建新对象所以拼接效率极高。2.3 底层统一扩容机制默认初始容量16当字符长度超出容量时自动扩容新容量 原容量 × 2 2如果扩容后仍然不够则直接扩容为当前所需最小长度。三、三者核心区别对比表类型可变性线程安全效率适用场景String不可变安全极低频繁创建新对象字符串极少修改、常量定义、参数存储StringBuffer可变安全synchronized中等多线程环境字符串拼接StringBuilder可变不安全无锁最高单线程高频字符串拼接99% 业务场景四、代码实战演示差异4.1 String 拼接产生大量新对象低效public class StringTest { public static void main(String[] args) { String str Java; // 每次拼接都会生成新对象原对象丢弃 for (int i 0; i 5; i) { str i; } System.out.println(str); } }原理每一次 底层都会 new 新 String 对象循环次数越多内存垃圾越多、效率越低。4.2 StringBuilder 单线程高效拼接推荐public class StringBuilderTest { public static void main(String[] args) { StringBuilder sb new StringBuilder(Java); for (int i 0; i 5; i) { // 原地扩容修改不创建新对象 sb.append(i); } System.out.println(sb); } }优势全程只有一个对象数组动态扩容性能碾压 String。4.3 StringBuffer 多线程安全演示public class StringBufferTest { public static void main(String[] args) { StringBuffer sb new StringBuffer(); // 多线程并发拼接不会错乱 new Thread(() - { for (int i 0; i 100; i) { sb.append(A); } }).start(); new Thread(() - { for (int i 0; i 100; i) { sb.append(B); } }).start(); } }原理append 方法被synchronized修饰保证多线程串行执行数据不错乱。五、效率实测代码直观差距public class SpeedTest { public static void main(String[] args) { // String 耗时测试 long start1 System.currentTimeMillis(); String str ; for (int i 0; i 10000; i) { str i; } System.out.println(String耗时 (System.currentTimeMillis() - start1)); // StringBuilder 耗时测试 long start2 System.currentTimeMillis(); StringBuilder sb new StringBuilder(); for (int i 0; i 10000; i) { sb.append(i); } System.out.println(StringBuilder耗时 (System.currentTimeMillis() - start2)); } }结论循环次数越大String 和 StringBuilder 效率差距越恐怖项目中循环拼接禁止使用 String。六、开发最佳实践避坑指南1.少量固定字符串、常量定义直接使用 String简洁安全2.单线程循环拼接、字符串累加优先 StringBuilder效率最高3.多线程并发拼接字符串必须使用 StringBuffer保证线程安全4. 绝对避免for 循环内使用 String 直接拼接极易造成性能问题。七、面试极简必背总结1. String底层 final 数组不可变每次修改新建对象效率低线程安全2. StringBuffer底层可变数组方法加锁线程安全、效率一般适用于多线程3. StringBuilder底层可变数组无锁线程不安全、效率最高适用于单线程4. 扩容机制默认容量16扩容公式原容量*22。八、文末小结三者的本质区别只有两个字符串是否可变、是否线程安全。String 适合“读”不适合“改”StringBuilder 适合单线程高频修改StringBuffer 适合多线程并发修改。掌握底层数组特性与扩容原理既能轻松应对面试也能彻底规避项目中字符串性能劣化、并发错乱等经典 Bug。