String、StringBuffer和StringBuilder三者的关系

前言

昨天跟老大面试一个中级开发,前面聊得不错,问到java基础时,问了一个经典的问题:String类为什么是不可变的?回答到:因为这个类被final修饰了,所以不可变,然后就没了。老大苦笑一下,面试直接结束。
String类是final的,这是毋容置疑的,但是这肯定不是面试官想听到的答案。回去我看了看String源码,想写写关于String、StringBuffer、StringBuilder这三者的关系。

正文

String类为什么是不可变的?

看源码会发现,无论是String还是StringBuffer或者StringBuilder他们类前都public final修饰了。所以说因为String类被final修饰了,所以不可变。这个答案肯定是不准确的。我们在创建字符串肯定通过构造方法。每个构造方法都需要value,关键就是这个value。

String类中value其实就是个byte[],但是这个byte[]数组被fianl修饰了,这就意味着数组一旦创建长度不可以改变,被final修饰的变量是不可变,也就是当这个数组指向某个对象后,它就不可以改变了,所以String是不可变的。

	public String() {
        this.value = "".value;
        this.coder = "".coder;
    }
	
    @Stable
    private final byte[] value;

StringBuffer/StringBuilder为什么是可变的?

StringBuffer/StringBuilder中value其实也是个就是个byte[],但是这个byte[]数组并没没有被fianl修饰,所以可以随意改变他的引用,当调用append()时,他会直接拼接到这个对象后面。StringBuffer和StringBuilder的初始化容量都是16,当容器满了会调用数组的arraycopy()方法拷贝原始数据,然后调用expandCapacity()进行可扩容,扩容大小为原大小的2倍+2。

   public StringBuilder() {
        super(16);
    }
    
	public StringBuffer() {
        super(16);
    }
    
 	byte[] value;

StringBuffer和StringBuilder的区别:

查看源码发现这两个类当中所有方法都是一样的,唯一不同的就是StringBuffer中的每个方法都比StringBuilder多一个修饰符synchronized(同步锁)。所以StringBuffer在多线程是安全的,StringBuilder是不全的。

public synchronized int compareTo(StringBuffer another) {
        return super.compareTo(another);
    }
    
 public int compareTo(StringBuilder another) {
        return super.compareTo(another);
    }

总结:

String:不建议使用String操作字符串。
StringBuffer:适用于多线程操作字符串,安全,但是速度慢(有同步锁,多线程排队)。
StringBuilder:适用于单线程操作字符串,非多线程安全,但是速度快。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值