当前位置: 代码网 > it编程>编程语言>Java > Java中String、StringBuffer和StringBuilder底层实现深入剖析

Java中String、StringBuffer和StringBuilder底层实现深入剖析

2026年01月08日 • Java •我要评论
前言这三个类都是 java.lang 包下的字符串处理类,但它们在设计理念、内部实现和适用场景上存在显著差异。1. 全面对比表比较维度stringstringbufferstringbuilder可变

前言

这三个类都是 java.lang 包下的字符串处理类,但它们在设计理念、内部实现和适用场景上存在显著差异。

1. 全面对比表

比较维度stringstringbufferstringbuilder
可变性不可变(immutable)
内容一旦创建无法修改
可变(mutable)
支持原地修改
可变(mutable)
支持原地修改
线程安全天然线程安全(不可变对象)线程安全
关键方法(如 append、insert)加了 synchronized 锁
非线程安全
无任何同步机制
性能修改操作最慢(频繁创建新对象)中等(有锁开销,但比 string 好)最高(无锁,单线程下最优)
内部存储底层是 final char[] value(jdk 7+)
jdk 8 前是 char[],不可扩容
底层是 char[] value,可动态扩容底层是 char[] value,可动态扩容(实现几乎相同)
容量扩容机制无(固定长度)默认容量 16,扩容时新容量 = (旧容量 * 2) + 2同 stringbuffer:默认 16,扩容时新容量 = (旧容量 * 2) + 2
内存占用每次修改产生新对象 + 新 char[],gc 压力大共享同一 char[],内存高效同 stringbuffer,内存高效
字符串常量池支持常量池缓存(字面量可复用)不支持常量池不支持常量池
引入版本jdk 1.0jdk 1.0jdk 1.5(为单线程优化而新增)
继承关系继承 abstractstringbuilder,实现 charsequence、serializable、comparable继承 abstractstringbuilder,实现 appendable 等继承 abstractstringbuilder,实现 appendable 等
方法同步无需同步大部分修改方法(如 append、delete)都是 synchronized无 synchronized
典型使用场景常量字符串、键值存储、配置信息多线程频繁拼接(如日志记录、共享缓冲)单线程频繁拼接(如 json 构建、循环拼接)——现代项目首选
tostring() 实现返回自身(缓存优化 jdk 7+)新建 string 对象(调用 arrays.copyof)同 stringbuffer

2. 底层实现深入剖析

  • string 的不可变性:

    // jdk 源码简化版
    public final class string {
        private final char[] value;  // final 修饰,不可重新赋值
        private final int hash;      // 缓存 hashcode
    }
    

    任何“修改”操作(如 concat、replace)都会 new string() 并复制 char[],原对象不变。

  • stringbuffer / stringbuilder 的可变性:
    两者都继承自 abstractstringbuilder:

    abstract class abstractstringbuilder {
        char[] value;      // 非 final,可扩容
        int count;         // 当前长度
    }
    
    • append 等操作直接操作 value 数组。
    • 扩容时:arrays.copyof 创建更大数组,复制旧内容。

    关键区别:stringbuffer 的公共方法加了 synchronized:

    // stringbuffer 示例
    public synchronized stringbuffer append(string str) { ... }
    
    // stringbuilder 示例
    public stringbuilder append(string str) { ... }  // 无 synchronized
    

3. 性能对比实测(循环 10 万次拼接)

public class test {
    public static void main(string[] args) {
        int times = 100000;

        // string
        long start = system.nanotime();
        string s = "";
        for (int i = 0; i < times; i++) {
            s += i;
        }
        system.out.println("string 用时: " + (system.nanotime() - start) / 1e6 + " ms");

        // stringbuilder
        start = system.nanotime();
        stringbuilder sb = new stringbuilder();
        for (int i = 0; i < times; i++) {
            sb.append(i);
        }
        system.out.println("stringbuilder 用时: " + (system.nanotime() - start) / 1e6 + " ms");

        // stringbuffer
        start = system.nanotime();
        stringbuffer sbf = new stringbuffer();
        for (int i = 0; i < times; i++) {
            sbf.append(i);
        }
        system.out.println("stringbuffer 用时: " + (system.nanotime() - start) / 1e6 + " ms");
    }
}

典型运行结果(jdk 17,普通电脑):

  • string:约 3000~5000 ms(极慢,产生海量临时对象)
  • stringbuilder:约 10~20 ms
  • stringbuffer:约 15~30 ms(略慢于 builder,因锁开销)

可见,频繁修改时 stringbuilder 性能遥遥领先。

4. 编译器优化小秘密

  • 单次 + 操作:jvm 会自动优化为 stringbuilder:

    string result = "a" + "b" + "c";  // 编译后相当于 new stringbuilder().append("a").append("b").append("c").tostring()
    
  • 循环中 + 操作:不会跨循环优化,仍建议手动用 stringbuilder。

5. 选择指南(实战总结)

  1. 内容几乎不修改 → 用 string(最安全、支持常量池)。

  2. 多线程 + 频繁修改 → 用 stringbuffer(虽慢点但安全)。

  3. 单线程 + 频繁修改 → 必须用 stringbuilder(性能最佳,99% 场景适用)。

  4. 已知长度大 → 提前指定容量,避免扩容:

    stringbuilder sb = new stringbuilder(10000);  // 预分配
    
  5. 现代替代方案:复杂场景可考虑 string.join()、string.format() 或流式操作,但核心拼接仍推荐 stringbuilder。

6. 常见误区澄清

  • 误区:stringbuffer 完全过时了 → 错!在多线程共享同一缓冲时仍有价值。
  • 误区:stringbuilder 线程不安全就不能用 → 大多数业务是单线程,安全使用即可。
  • 误区:string 完全不能用于拼接 → 小量拼接没问题,大量必须避免。

总结

到此这篇关于java中string、stringbuffer和stringbuilder底层实现的文章就介绍到这了,更多相关java中string、stringbuffer和stringbuilder内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

赞 (0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com