JDK源码分析之StringBuffer篇

 
  1. public final class StringBuffer

  2. extends AbstractStringBuilder

  3. implements java.io.Serializable, CharSequence

  4. {

  5. .....

  6. }


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

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

 
  1. abstract class AbstractStringBuilder implements Appendable, CharSequence {

  2. /**

  3. * The value is used for character storage.与String类一样,定义了一个char类型的数组存储值

  4. */

  5. char value[];

  6.  
  7. /**

  8. * The count is the number of characters used.

  9. */

  10. int count;

  11.  
  12. /**

  13. * This no-arg constructor is necessary for serialization of subclasses.

  14. */

  15. AbstractStringBuilder() {

  16. }

  17.  
  18. /**

  19. * Creates an AbstractStringBuilder of the specified capacity.

  20. */

  21. AbstractStringBuilder(int capacity) {

  22. value = new char[capacity];

  23. }

 
  1. public AbstractStringBuilder append(String str) {

  2. if (str == null) str = "null";

  3. int len = str.length();

  4.  
  5. if (len == 0) return this;

  6.  
  7. int newCount = count + len;

  8.  
  9. if (newCount > value.length)

  10. expandCapacity(newCount);//这一步主要是扩容

  11.  
  12. str.getChars(0, len, value, count);

  13. count = newCount;

  14. return this;

  15. }

 
  1. void expandCapacity(int minimumCapacity) {

  2. int newCapacity = (value.length + 1) * 2;//首先定义一个是原容量的2倍大小的值

  3. if (newCapacity < 0) {

  4. newCapacity = Integer.MAX_VALUE;

  5. } else if (minimumCapacity > newCapacity) {<span style="font-family: Arial, Helvetica, sans-serif;">//这一步主要是判断,取最大的值做新的数组容量大小</span>

  6. newCapacity = minimumCapacity;

  7. }

  8. value = Arrays.copyOf(value, newCapacity);//最后进行扩容

  9. }

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

 
  1. public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {

  2. if (srcBegin < 0) {

  3. throw new StringIndexOutOfBoundsException(srcBegin);

  4. }

  5. if (srcEnd > count) {

  6. throw new StringIndexOutOfBoundsException(srcEnd);

  7. }

  8. if (srcBegin > srcEnd) {

  9. throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);

  10. }/*前面三个判断主要是为了安全验证,这一步才是重点:将在原来的数组上追加新数组*/

  11. System.arraycopy(value, offset + srcBegin, dst, dstBegin,

  12. srcEnd - srcBegin);

  13. }

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

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

 
  1. public interface CharSequence {

  2.  
  3. int length();

  4.  
  5. char charAt(int index);

  6.  
  7. CharSequence subSequence(int start, int end);

  8.  
  9. public String toString();

  10.  
  11. }

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

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

先看看几个构造方法:

 
 
  1. public StringBuffer() {

  2. super(16);//定义一个长度为16的数组

  3. }

  4.  
  5. /**

  6. * Constructs a string buffer with no characters in it and

  7. * the specified initial capacity.

  8. *

  9. * @param capacity the initial capacity.

  10. * @exception NegativeArraySizeException if the <code>capacity</code>

  11. * argument is less than <code>0</code>.

  12. */

  13. public StringBuffer(int capacity) {

  14. super(capacity);

  15. }

  16.  
  17. /**

  18. * Constructs a string buffer initialized to the contents of the

  19. * specified string. The initial capacity of the string buffer is

  20. * <code>16</code> plus the length of the string argument.

  21. *

  22. * @param str the initial contents of the buffer.

  23. * @exception NullPointerException if <code>str</code> is <code>null</code>

  24. */

  25. public StringBuffer(String str) {

  26. super(str.length() + 16);

  27. append(str);//该方法在上面已经分析过

  28. }

append()方法:

 
  1. public synchronized StringBuffer append(String str) {

  2. super.append(str);

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

  4. }

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

toString():

 
  1. public synchronized String toString() {

  2. return new String(value, 0, count);//相当于重新生成一个String对象

  3. }

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

猜你喜欢

转载自blog.csdn.net/qq_36312376/article/details/81388142