当前位置: 首页 > news >正文

String、StringBuilder、StringBuffer 的本质区别

作为 Java 开发者,String、StringBuilder、StringBuffer 这三个类几乎每天都在用。但面试官总爱问这道题,因为它背后藏着 JVM 内存模型、线程安全、性能优化等核心知识点。今天我们从本质出发,彻底把这三个类讲透。

一、String 为什么不可变?

看一下 JDK 源码,String 类被 final 修饰不能被继承,底层字符数组 value 也是 final 的,一旦赋值就不能改变引用。所以当你写下:

String s = "hello";

s = s + " world";

你以为是在修改 s,实际上是创建了一个新的 String 对象 "hello world",然后让 s 指向这个新对象。原来的 "hello" 对象还在堆里,等待 GC 回收。

这就是为什么在循环里用 String 拼接字符串会有性能问题,每次拼接都在创建新对象,内存抖动严重。

经典面试题:字符串常量池

String a = "hello";

String b = "hello";

String c = new String("hello");

a == b 结果是 true(常量池复用),a == c 结果是 false(new 在堆上创建新对象),a.equals(c) 结果是 true。字面量赋值时,JVM 会先检查常量池里有没有这个字符串,有就直接复用。

二、StringBuilder:高性能的可变字符序列

StringBuilder 是 JDK 1.5 引入的,专门解决 String 频繁拼接的性能问题。底层也是 char 数组,但这个数组是可变的。

低效写法:

String result = "";

for (int i = 0; i小于10000; i++) result += i;

高效写法:

StringBuilder sb = new StringBuilder();

for (int i = 0; i小于10000; i++) sb.append(i);

性能差距可能达到 500 倍以上!因为 String 每次 += 都创建新对象,而 StringBuilder 在原数组上扩容追加。

扩容机制

StringBuilder 默认容量 16,超出时扩容为(原容量 x 2)+ 2。如果你提前知道字符串的大概长度,可以在构造时指定初始容量:new StringBuilder(1024),减少扩容次数。

三、StringBuffer:线程安全版

StringBuffer 比 StringBuilder 早出现,API 几乎一模一样,最大的区别是所有方法都加了 synchronized 关键字,保证多线程安全,但也带来了性能开销。

什么时候用 StringBuffer?只有多线程共享同一个字符串构建器时才需要。如果 StringBuilder 只是方法内的局部变量,每个线程都有自己的栈帧,不存在共享,用 StringBuilder 完全没问题。

四、三者核心对比

String:不可变、线程安全、频繁修改时性能差、适合字符串不变或少量拼接

StringBuilder:可变、非线程安全、性能最好、适合单线程频繁拼接

StringBuffer:可变、线程安全、性能略差、适合多线程共享拼接

五、编译器优化的坑

很多人以为 String 拼接一定慢,其实不完全对。Java 编译器会对常量拼接做优化:String s = "hello" + " world"; 在编译期就变成了 "hello world"。

但在循环里就不一样了,每次循环都会 new 一个 StringBuilder,所以循环拼接一定要手动用 StringBuilder。

总结

String 的不可变性是核心设计,带来了线程安全和常量池复用的好处,代价是频繁修改时的性能损耗。StringBuilder 和 StringBuffer 都是为了解决这个问题而生,区别只在于是否需要线程安全。实际开发中 99% 的场景用 StringBuilder 就够了。

end
===往期精彩文章复习回顾===
1.SpringBoot 插件化开发模式,真香啊! 2.一行代码,实现请假审批流程(Java版) 3.血泪教训,8 个线程池最佳实践和坑 4.是时候优化了:告别繁琐操作,实现一次登录产品互通! 5.太失败了,工作5年后,我才知道 Java 泛型的上限和下限~

最近整理一份资料《程序员学习手册》,覆盖了 Java技术、面试题精选、操作系统基础知识、计算机基础知识、Linux教程、计算机网络等等。

获取方式:点“在看,关注公众号Java大数据修炼之道并回复PDF领取,更多内容陆续奉上。

长按识别下方二维码关注后回复关键字:PDF领取

你想学的java知识这里都有,长按下方图片识别关注我们吧~

如喜欢本文请点击右上角,把文章分享到朋友圈 因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享 点分享点收藏点在看
http://www.jsqmd.com/news/545496/

相关文章:

  • OpCore-Simplify:5分钟搞定黑苹果配置的终极指南
  • OpenClaw+nanobot开发提效:日志分析自动化实践
  • Pixel Fashion Atelier效果展示:同一人物基底在不同皮装款式(机车/骑士/朋克)下的风格迁移
  • tkinter表格神器tkintertable实战:5分钟搞定可拖拽编辑的数据表格(附完整代码)
  • 7步系统优化解决方案:使用Win11Debloat实现Windows性能提升
  • 磁致伸缩应变定义
  • 高精度气象预测越来越多,决策反而越来越慢?企业气象系统最大的内耗正在这里
  • 音频工程师不会告诉你的4路回采秘籍:OBS直播/录音棚监控的隐藏技巧
  • M2LOrder模型与Git版本控制:协作开发情感分析项目实践
  • 技术赋能下B端拓客:号码核验行业的痛点突围与发展新方向,氪迹科技法人股东号码筛选系统,阶梯式价格
  • 别再自己造轮子了!用MONAI Model Zoo里的预训练模型,5分钟搞定医学影像AI项目
  • LaTeX公式转图片终极指南:3分钟学会专业数学公式可视化
  • Wan2.2-I2V-A14B实操手册:output路径自定义+批量视频导出脚本编写
  • 深入解析面向对象编程的继承机制
  • 电商个人卖家:OpenClaw+Qwen3.5-9B自动化商品上架
  • Qwen3-ASR-1.7B在Linux系统下的高效部署与性能优化
  • OpenClaw跨平台同步:ollama-QwQ-32B任务在Mac与Windows间无缝切换
  • BGC-Argo数据处理实战:叶绿素浓度校正的5个关键步骤(附Python代码)
  • 软考高项-项目绩效域-知识点及考点预测
  • SVGnest智能排版优化器:5分钟掌握高效材料利用率提升技巧
  • Python测试脚本开发:核心语法速成
  • OpenClaw+nanobot成本优化:4B模型本地化部署实测
  • 安全第一:OpenClaw+nanobot镜像敏感操作权限管控方案
  • 别再乱接电阻了!I2C总线上拉电阻阻值怎么选?实测对比不同阻值对通信稳定性的影响
  • Beat Saber版本管理终极指南:用BSManager告别游戏更新烦恼
  • 基于Phi-4-mini-reasoning的自动报告生成系统:科研论文摘要优化
  • 5分钟快速上手PT助手插件:你的浏览器种子下载神器
  • PP-DocLayoutV3快速上手:中文文档优化设计,精准识别正文标题图片
  • Java异常处理实战:常见问题与解决方案
  • 从零开始:Bibliometrix在RStudio中的安装与实战指南