Java 中 String、StringBuffer、StringBuilder 的区别

核心区别概览

特性 String StringBuffer StringBuilder
可变性 不可变 可变 可变
线程安全 安全(不可变) 安全(方法加同步锁) 不安全
性能 最差(频繁创建对象) 中等 最好
使用场景 少量拼接、常量 多线程拼接 单线程拼接

详细对比

1. 可变性

String 是不可变类(immutable)。每次对 String 进行修改(如 += 拼接)时,都会创建一个新的 String 对象,旧对象被丢弃。

ini 复制代码
String s = "";
for (int i = 0; i < 100000; i++) {
    s += 'a';  // 每次循环都创建新对象,性能极差
}

StringBuffer 和 StringBuilder 都是可变类(mutable)。它们内部维护一个字符数组,append 操作直接修改数组内容,不会创建新对象。

ini 复制代码
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) {
    sb.append('a');  // 直接修改内部数组
}

StringBuffer sf = new StringBuffer();  
for (int i = 0; i < 100000; i++){  
    sf.append('a');  
}

2. 线程安全性

String 因为不可变,天然线程安全。

StringBuffer 的关键方法都加了 synchronized 关键字,保证多线程环境下的数据一致性:

java 复制代码
// 可以拿这个玩一下10线程抢占
public static void StringBufferPool() throws InterruptedException{  
    String[] aToz = new String[]{  
            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"  
    };  
  
    //10线程  
    Runnable task = ()->{  
        StringBuffer sb = new StringBuffer();  
  
        for(int i=0;i<10;i++){  
            sb.append(aToz[(int) (Math.random()*26)]);  
            System.out.println(Thread.currentThread().getName()+"当前字符:"+sb.toString());  
        }  
    };  
  
    ExecutorService es = Executors.newFixedThreadPool(10);  
    for (int k = 0; k< 10 ;k++){  
        es.execute(task);  
    }  
  
    es.shutdown();  
    es.awaitTermination(100000, TimeUnit.MILLISECONDS);  
}

部分结果:

makefile 复制代码
pool-1-thread-2当前字符:r
pool-1-thread-10当前字符:b
pool-1-thread-10当前字符:bc
pool-1-thread-10当前字符:bcc
pool-1-thread-9当前字符:d
pool-1-thread-4当前字符:j
pool-1-thread-5当前字符:d
pool-1-thread-5当前字符:df
pool-1-thread-5当前字符:dfm
pool-1-thread-7当前字符:p

StringBuilder 没有同步机制,线程不安全,但因此性能更高。

3. 性能对比

类型 耗时(毫秒) 原因
String 3883 每次拼接创建新对象,GC 压力大
StringBuffer 48 有同步开销
StringBuilder 2 无同步开销,性能最优
yaml 复制代码
3883
2
48

4. 使用场景

  • String:字符串内容不经常变化的场景,如常量、少量拼接
  • StringBuffer:多线程环境下的字符串拼接
  • StringBuilder :单线程环境下的字符串拼接(推荐)

总结

  1. 单线程拼接 :优先使用 StringBuilder
  2. 多线程拼接 :使用 StringBuffer
  3. 避免 :在循环中使用 String 进行大量拼接
相关推荐
郑州光合科技余经理4 分钟前
出海外卖平台:支付对接为什么要和下单收款分开
android·java·开发语言·前端·后端·php·ai编程
我是人✓11 分钟前
Spring框架的事务管理
java·后端·spring
javachen__24 分钟前
JsonView:一套VO实现多角色字段返回
java·linux·服务器
行者-全栈开发41 分钟前
SpringBoot 生产环境踩坑实录:10个真实故障案例与教训
java·spring boot·后端
李福春43 分钟前
斗破Google ADK Java苍穹-第7境斗皇-御天地-Harness治理
java·人工智能·python·深圳同盟·腾讯云架构师技术同盟·adk java·harness 治理
Wang's Blog1 小时前
Java 项目部署之 Docker工具快速入门: 容器命令练习:创建、改文件、重启到删除的完整闭环
java·开发语言·docker
我是人✓1 小时前
Java面向对象核心特性深度解析
java·前端·算法
Wx-bishekaifayuan1 小时前
springboot线上中医药养生平台管理系统36753-计算机课程设计、毕业设计
java·spring boot·后端·spring·课程设计·express·旅游
Wx-bishekaifayuan1 小时前
springboot大学生就业平台47691-计算机课程设计、毕业设计
java·spring boot·后端·elasticsearch·课程设计·express·旅游
汤姆yu1 小时前
基于springboot+vue的企业OA办公系统
java·spring boot·后端·oa办公