String、StringBuffer、StringBuilder的区别,String为什么是不可变的

String是字符串常量
StringBuffer、StringBuilder是字符串变量
为什么String是字符串常量
看一个例子:

String s = "abcd" ;
s = s+1;
 System.out.println(s);

在视觉上看s确实变了,实际上这里第一行的s是对String对象的引用,指向String对象”abcd”,第二行又创建了一个新的String对象来存储新的值,然后s对String对象的引用重新指向这个新的String对象。

在源代码中我们可以看到,String在创建的时候就被声明为final变量

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

    @Stable
    private final byte[] value;

    private final byte coder;

    private int hash; // Default to 0
……

这表示String类是不可以被继承的,换句话说,String str = “abcd”,str的引用可以明确地看到指向的是String类型的对象,而不是String的子类,这样从JVM的角度考虑,确实提升了一定的效率,且private final byte[] value;也是final,说明里面的byte[]数组是不可改变的,而且数组的长度一旦固定,就没有办法进行扩容,也就是说String对象一旦创建,byte数组的长度刚好够存字符串的长度,以后就没有办法进行扩容了,这也就是为什么String对象的值不能改变的原因
StringBuffer和StringBuilder的区别
StringBuffer和StringBuilder都继承自AbstractStringBuilder类,在AbstractStringBuilder类中也是使用byte数组保存字符串的值,但是没有使用final修饰,所以这两种对象是可变的

abstract class AbstractStringBuilder implements Appendable, CharSequence {
   
    byte[] value;

    byte coder;

    int count;
……

在源码中可以看到StringBuffer对方法或调用的方法加了synchronized关键字(同步锁),是线程安全的,也就是多线程修改同一个StringBuffer对象的时候,过程是同步的,但这也导致了StringBuffer的效率下降,为了提高单线程下StringBuffer的效率,在jdk1.5中新增了StringBuilder,因为没有了同步操作,所以StringBuilder的多线程安全性降低,是非线程安全的;
StringBuffer和StringBulider源码

性能方面
执行速度:String<StringBuffer<StringBuilder
每次对String对象进行操作时都会生成一个新的String对象,然后引用指向新的String对象,StringBuffer每次都会对StringBuffer对象本身进行操作,相同情况下,StringBuilder相对StringBuffer能够获得一定的性能提升,但却要冒多线程不安全的风险。
总结
操作少量数据使用String
单线程操作字符串缓冲区下操作大量数据使用StringBuilder
多线程操作字符串缓冲区下操作大量数据使用StringBuffer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值