【Java基础面试题026】Java中的String、StringBuffer和StringBuilder的区别是什么?

回答重点

他们都是Java中处理字符串的类,区别主要体现在可变性线程安全性能上

1)String

  • **不可变:**String是不可变类,字符串对象创建,存储在堆中,字符串内容存储在字符串常量池中,一旦创建内容无法更改。每次对String进行修改操作(如拼接、截取等),都会创建新的字符串常量池对象
  • **适合场景:**String适合于字符串内容不会频繁变化的场景

2)StringBuffer

  • **可变:**StringBuffer是可变的,因为底层是字符数组,(字符是局部变量存栈上,跟着方法一起的生命周期,如果是成员变量存在堆中,跟着对象)任何操作都是对数组操作,而不是创建新的对象,可以进行字符串的追加、删除、插入等操作
  • **线程安全:**StringBuffer是线程安全的,内部使用了synchronized关键字保证多线程环境下的安全性
  • **适合场景:**适用于多线程环境中需要频繁修改字符串的场景

3)StringBuilder

  • **可变:**也是可变的,提供了与StringBuffer类似的操作方法
  • **非线程安全:**线程不安全
  • **性能:**由于少了同步的操作,性能开销比StringBuffer小
  • 适合场景:适用于单线程环境中需要大量修改字符串的场景

可以看我的另一篇博客:【Java】StringBuilder类和StringBuffer类的简单教程-CSDN博客

扩展知识

Java8中的优化

在Java8以后,编辑器会对字符串的常量拼接做优化,将字符串拼接转换为StringBuilder操作。种优化提高了代码性能,但是在动态拼接或多线程场景下,手动使用StringBuilder 和 StringBuffer 仍然更合适。

从演进角度看待三者

String 是Java 中基础且重要的类,并且String 也是Immutable 类的典型实现,被声明为finalclass,除了hash

这个属性其它属性都声明为final。

因为它的不可变性,所以例如拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所景响。

StringBuffer就是为了解决大量拼接字符串时产生很多中间对象问题而提供的一个类,提供append和insert方法,可以将字符串添加到已有序列的末尾或指定位置。

它的本质是一个线程安全的可修改的字符序列,把所有修改数据的方法都加上了synchronized。但是保证了线程安全是需要性能的代价的。

在很多情况下我们的字符串拼接操作不需要线程安全,这时候StringBuilder 登场了,StringBuilder 是JDK1.5 发布的,它和StringBuffer本质上没什么区别,就是去掉了保证线程安全的那部分,减少了开销。

StringBuffer 和 StringBuilder 二者都继承了 Abst ractStringBuilder,底层都是利用可修改的 char 数组(JDK 9以后是byte 数组)。

所以如果我们有大量的字符串拼接,如果能预知大小的话最好在new StringBuffer 或者StringBuilder 的时候设置好capacity,避免多次扩容的开销(扩容要抛弃原有数组,还要进行数组拷贝创建新的数组)。

相关推荐
虚行6 分钟前
Python学习入门
开发语言·python·学习
总有刁民想爱朕ha10 分钟前
Python自动化从入门到实战(23):Python打地鼠游戏开发
开发语言·python·游戏开发
曹牧11 分钟前
C#:函数默认参数
开发语言·c#
黄焖鸡能干四碗20 分钟前
MES生产执行制造系统建设(Java+Mysql)
java·大数据·开发语言·信息可视化·需求分析
workflower23 分钟前
跨链协同制造中的服务博弈与激励机制
开发语言·软件工程·制造·需求分析·个人开发·结对编程
liulilittle28 分钟前
Y组合子剖析:C++ 中的递归魔法
开发语言·c++·编程语言·函数式编程·函数式·函数编程·y组合子
舒克日记28 分钟前
基于springboot的民谣网站的设计与实现
java·spring boot·后端
凤山老林2 小时前
新一代Java应用日志可视化与监控系统开源啦
java·后端·开源
流星白龙2 小时前
【Qt】7.信号和槽_connect函数用法(2)
java·数据库·qt
金涛03193 小时前
QT-day2,信号和槽
开发语言·qt·命令模式