【Java源码学习】关于String、StringBuffer、StringBuilder

    说来惭愧,用Java开发这么久了都没有好好研究下Java的源代码,很多东西知其然却不知其所以然,导致现在对Java还是一知半解。趁这段时间慢慢研究下Java的源码,巩固下基础知识。

    闲话不多说,先来看一下最常见的String、StringBuffer、StringBuilder这三个类的实现吧。为什么说String是不可变的,而StringBuffer、StringBuilder却是可变的。

    首先这三个类是用char[] value来存储值的,而String类只能在构造函数中设置value长度和值。也就是说如果要改变String的值必须要新创建一个对象,这样在我们进行大量的字符串操作的时候就会产生大量的String对象,即使很多String对象的值都是相等的。为了解决这个问题Java引入了字符串缓存池的概念。就是将创建的String对象都放到缓存池中,如果String对象的值相等的话就使用缓存池中的对象,不再重新创建。这样就能解答诸如:
String a = new String("abc");
String b = new String("abc");
到底创建了几个对象。

    鉴于String类在大量字符串操作时产生大量对象的情况,Java又提供了两个类来解决这个问题,就是StringBuffer、StringBuilder,这两个类都继承自AbstractStringBuilder。先来看StringBuffer类的构造函数:
    public StringBuffer() {
	super(16);
    }

    public StringBuffer(String str) {
	super(str.length() + 16);
	append(str);
    }

父类中的构造函数
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

StringBuffer的默认大小是16,也是使用char[]来保存值,与String类不同的是它还提供了append方法来改变value的大小和值。当value的长度不够存储是,会自动进行扩容,默认新的长度为(value.length + 1) * 2,如果仍然长度不够则扩容为新字符串的长度。
    public synchronized StringBuffer append(String str) {
	super.append(str);
        return this;
    }

    public AbstractStringBuilder append(String str) {
	if (str == null) str = "null";
        int len = str.length();
	if (len == 0) return this;
	int newCount = count + len;
	if (newCount > value.length)
	    expandCapacity(newCount);
	str.getChars(0, len, value, count);
	count = newCount;
	return this;
    }

    void expandCapacity(int minimumCapacity) {
	int newCapacity = (value.length + 1) * 2;
        if (newCapacity < 0) {
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
	    newCapacity = minimumCapacity;
	}
        value = Arrays.copyOf(value, newCapacity);
    }


    StringBuilder提供了兼容StringBuffer的功能,那么StringBuffer与StringBuilder有什么区别呢?还是看代码:
StringBuffer类
    public synchronized StringBuffer append(String str) {
	super.append(str);
        return this;
    }



StringBuilder类
    public StringBuilder append(String str) {
	super.append(str);
        return this;
    }

很容易看出StringBuffer是保证同步的,而StringBuilder不是,因此StringBuilder的效率要高一些。所以一般推荐使用StringBuilder,但是涉及到多线程调用的需要使用StringBuffer。

你可能感兴趣的:(String,StringBuilder,StringBuffer,Java源码学习)