JDK源码分析之StringBuffer篇

public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
.....
}

StringBuffer类跟String类一样定义成final形式,主要是为了“效率”和“安全性”的考虑,若StringBuffer 被继承,由于它的高使用率,可能会降低它的性能。StringBuffer实现的接口Serializable的作用我们就不说了,再来看看StringBuffer继承的AbstractStringBuilder类和实现的CharSequence接口到底是干嘛的。

AbstractStringBuilder类:(这里仅简单介绍append方法简单,在这里细讲append,主要是在StringBuffer里直接调用父类的append,其他的类似。)

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.与String类一样,定义了一个char类型的数组存储值
     */
    char value[];

    /** 
     * The count is the number of characters used.
     */
    int count;

    /** 
     * This no-arg constructor is necessary for serialization of subclasses.
     */
    AbstractStringBuilder() {
    }

    /** 
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }


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;//首先定义一个是原容量的2倍大小的值
        if (newCapacity < 0) {
            newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {//这一步主要是判断,取最大的值做新的数组容量大小
	    newCapacity = minimumCapacity;
	}
        value = Arrays.copyOf(value, newCapacity);//最后进行扩容
 }


String类的getChar(...)函数:

public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > count) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }/*前面三个判断主要是为了安全验证,这一步才是重点:将在原来的数组上追加新数组*/
        System.arraycopy(value, offset + srcBegin, dst, dstBegin,
             srcEnd - srcBegin);
    }


AbstractStringBuilder类里定义了很多方法,在StringBuffer里是直接通过supper.XXX()调用的,这里就不细说了。


再来看看CharSequence接口是个什么东东:

public interface CharSequence {

    int length();

    char charAt(int index);

    CharSequence subSequence(int start, int end);

    public String toString();

}
看到了吧,定义了几个公共的方法,这里就不多说了。


--------------------------------       回到StringBuffer       -------------------------------------------

先看看几个构造方法:

 
public StringBuffer() {
	super(16);//定义一个长度为16的数组
 }

    /**
     * Constructs a string buffer with no characters in it and 
     * the specified initial capacity. 
     *
     * @param      capacity  the initial capacity.
     * @exception  NegativeArraySizeException  if the capacity
     *               argument is less than 0.
     */
    public StringBuffer(int capacity) {
	super(capacity);
    }

    /**
     * Constructs a string buffer initialized to the contents of the 
     * specified string. The initial capacity of the string buffer is 
     * 16 plus the length of the string argument.
     *
     * @param   str   the initial contents of the buffer.
     * @exception NullPointerException if str is null
     */
    public StringBuffer(String str) {
	super(str.length() + 16);
	append(str);//该方法在上面已经分析过
    }

append()方法:

public synchronized StringBuffer append(String str) {
	super.append(str);
        return this;//从这里可以看出不管执行多少次的append(String)方法,不会与String的字符串拼接那样new String(...)对象。
}

append用的修饰符是synchronized,说明是线程安全的,而StringBuilder没有这个修饰符。


toString():

public synchronized String toString() {
    	return new String(value, 0, count);//相当于重新生成一个String对象
}


其他方法就不介绍了,大同小异。








你可能感兴趣的:(JDK源码笔记)