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

【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,避免多次扩容的开销(扩容要抛弃原有数组,还要进行数组拷贝创建新的数组)。

http://www.lryc.cn/news/508168.html

相关文章:

  • 解析在OceanBase创建分区的常见问题|OceanBase 用户问题精粹
  • Flutter组件————Container
  • Java重要面试名词整理(二):SpringMyBatis
  • Excel生成DBC脚本源文件
  • Git进阶:本地或远程仓库如何回滚到之前的某个commit
  • linux 中文输入法设置的宏观思路 (****)
  • 271-基于XC7V690T的12路光纤PCIe接口卡
  • Semaphore UI安装和实践
  • Redis篇--常见问题篇7--缓存一致性2(分布式事务框架Seata)
  • Docker Compose 安装 Harbor
  • 使用docker compose安装gitlab
  • 大模型日报 2024-12-18
  • Linux安装mysql5.7
  • 【容器】k8s学习笔记原理详解(十万字超详细)
  • .NET重点
  • SMMU软件指南SMMU编程之虚拟机结构和缓存
  • Go 语言并发实战:利用协程处理多个接口进行数据融合
  • Redis Hash Tag 知识详解
  • 在 Ubuntu 上安装 Muduo 网络库的详细指南
  • Golang Gin Redis+Mysql 同步查询更新删除操作(我的小GO笔记)
  • nodejs搭配express网站开发后端接口设计需要注意事项
  • mysql 基于chunk机制是如何支持运行期间,动态调整buffer pool大小的
  • 智能客户服务:AI与大数据的革新力量
  • Python日常使用的自动化脚本
  • 代理模式(JDK,CGLIB动态代理,AOP切面编程)
  • 【Leetcode 热题 100】236. 二叉树的最近公共祖先
  • Go框架比较:goframe、beego、iris和gin
  • Kafka Streams 在监控场景的应用与实践
  • 数据结构 -- 二叉树
  • redis数据转移