您的位置:首页 > 编程语言 > Java开发

JDK源码分析之StringBuffer篇

2016-06-23 14:13 323 查看
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) {<span style="font-family: Arial, Helvetica, sans-serif;">//这一步主要是判断,取最大的值做新的数组容量大小</span>
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 <code>capacity</code>
*               argument is less than <code>0</code>.
*/
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
* <code>16</code> plus the length of the string argument.
*
* @param   str   the initial contents of the buffer.
* @exception NullPointerException if <code>str</code> is <code>null</code>
*/
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对象
}


其他方法就不介绍了,大同小异。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: