String、StringBuffer、StringBuilder的区别

本文详细对比了String、StringBuilder和StringBuffer在运行速度和线程安全性方面的差异。String适用于少量字符串操作,StringBuilder适用于单线程下大量操作,而StringBuffer则适合多线程环境。文章深入解析了JVM对字符串的处理机制,以及不同类在操作字符串时的效率和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这三个类之间的区别主要在两个方面,即运行速度和线程安全这两个方面:

1.运行速度:StringBuilder>StringBuffer>String

String最慢的原因:
String为字符串常量,用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。而StringBuilder和StringBuffer为字符串变量,即String对象一旦创建之后对象是不可更改的,但后者的对象是变量,是可以更改的。
String str = “abc”;
System.out.println(str);
str = str+“de”;
System.out.println(str);
如果运行这段代码会发现先输出“abc”,然后输出“abcde”,好像str这个对象被更改了,其实,这只是一种假象罢了,JVM对这几行代码是这样处理的,首先创建一个String对象str,并把“abc“赋值给str,然后在第三行中,其实JVM又创建了一个新的对象也命名为str,然后再把原来的str的值和”de“加起来再复制给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,所以,str实际并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,JAVA中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。
而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

使用String创建一个字符串时,首先会检查池中是否有值相同的字符串对象,如果有就直接返回引用,不会创建字符串对象;如果没有则新建字符串对象,返回对象引用,并且将新创建的对象放入池中。但是,通过new方法创建的String对象是不检查字符串常量池的,而是直接在堆中创建新对象,也不会把对象放入池中。上述原则只适用于直接给String对象引用赋值的情况。

String str1 = new String(“aa”); //不检查字符串常量池的,创建了两个对象
String str2 = “bb”; //检查字符串常量池的,创建了一个对像

2.线程安全

StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用StringBuffer,如果想转成String类型,可以调用StringBuffer的toString()方法。

Java.lang.StringBuffer线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。

StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append(“le”) 会使字符串缓冲区包含“startle”,而 z.insert(4, “le”) 将更改字符串缓冲区,使之包含“starlet”。
StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder对象被当作是一个包含字符序列的变长数组。

java.lang.StringBuilder是一个可变的字符序列,是JDK5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。

在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuffer.

总结一下

String:适用于少量字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用于多线程下在字符缓冲区进行大量操作的情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值