引言
StringBuffer 和 StringBuilder 的构造方法各有四种构造方法,它们各自的构造方法总体原理上是统一的,轻微之处有一个缓存区的置空操作。简略来讲能够把他们的构造方法了解成雷同的。
构造方法
无参结构
/**
* Constructs a string buffer with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuffer() {super(16);
}
/**
* Constructs a string builder with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuilder() {super(16);
}
StringBuffer 和 StringBuilder 的无参构造方法继承的是 AbstractStringBuilder 抽象类中的 AbstractStringBuilder(int capacity)
办法。
/**
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {value = new char[capacity];
}
AbstractStringBuilder(int capacity)
办法底层是一个默认容量为 capacity=16
的字符数组,由此能够晓得 StringBuffer 和 StringBuilder 无参构造方法结构出的对象的初始容量为 16,能够用 capacity()办法查看。
System.out.println(stringBuilder.capacity());
System.out.println(stringBuffer.capacity());
有参结构
① 自定义容量
结构一个容量自定义的 StringBuffer 或 StringBuilder 对象,传入 int 类型的 capacity 自定义容量。
/**
* 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}
* argument is less than {@code 0}.
*/
public StringBuffer(int capacity) {super(capacity);
}
/**
* Constructs a string builder with no characters in it and an
* initial capacity specified by the {@code capacity} argument.
*
* @param capacity the initial capacity.
* @throws NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
public StringBuilder(int capacity) {super(capacity);
}
这个办法和无参结构走的都是 AbstractStringBuilder(int capacity)
办法,和下面无参构造方法不同的是 capacity 参数,无参结构默认capacity=16
,而有参结构中capacity=capacity
(自定义的)
② 字符串定义容量
传入一个字符串 str, 使得 capacity= str.length() + 16
,再调用 append() 办法进行解决。
/**
* Constructs a string buffer initialized to the contents of the
* specified string. The initial capacity of the string buffer is
* {@code 16} plus the length of the string argument.
*
* @param str the initial contents of the buffer.
*/
public StringBuffer(String str) {super(str.length() + 16);
append(str);
}
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
/**
* Constructs a string builder initialized to the contents of the
* specified string. The initial capacity of the string builder is
* {@code 16} plus the length of the string argument.
*
* @param str the initial contents of the buffer.
*/
public StringBuilder(String str) {super(str.length() + 16);
append(str);
}
@Override
public StringBuilder append(String str) {super.append(str);
return this;
}
Super()办法和下面两个是同一个办法,不同的是是 StringBuffer 办法中会把缓冲区进行置空操作 toStringCache = null
, 再走append()
办法。
/**
* Appends the specified string to this character sequence.
* <p>
* The characters of the {@code String} argument are appended, in
* order, increasing the length of this sequence by the length of the
* argument. If {@code str} is {@code null}, then the four
* characters {@code "null"} are appended.
* <p>
* Let <i>n</i> be the length of this character sequence just prior to
* execution of the {@code append} method. Then the character at
* index <i>k</i> in the new character sequence is equal to the character
* at index <i>k</i> in the old character sequence, if <i>k</i> is less
* than <i>n</i>; otherwise, it is equal to the character at index
* <i>k-n</i> in the argument {@code str}.
*
* @param str a string.
* @return a reference to this object.
*/
public AbstractStringBuilder append(String str) {if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
这外面波及到了他们的扩容机制,见下:
③ 结构蕴含与指定的 {@code CharSequence} 雷同的字符
CharSequence 指的是(s = null || s = (String)s || s = AbstractStringBuffer)s || AbstractStringBuilder)s)
/**
* Constructs a string buffer that contains the same characters
* as the specified {@code CharSequence}. The initial capacity of
* the string buffer is {@code 16} plus the length of the
* {@code CharSequence} argument.
* <p>
* If the length of the specified {@code CharSequence} is
* less than or equal to zero, then an empty buffer of capacity
* {@code 16} is returned.
*
* @param seq the sequence to copy.
* @since 1.5
*/
public StringBuffer(CharSequence seq) {this(seq.length() + 16);
append(seq);
}
/**
* Constructs a string builder that contains the same characters
* as the specified {@code CharSequence}. The initial capacity of
* the string builder is {@code 16} plus the length of the
* {@code CharSequence} argument.
*
* @param seq the sequence to copy.
*/
public StringBuilder(CharSequence seq) {this(seq.length() + 16);
append(seq);
}
最终走的 append()
办法,同样也波及扩容机制。
// Documentation in subclasses because of synchro difference
@Override
public AbstractStringBuilder append(CharSequence s) {if (s == null)
return appendNull();
if (s instanceof String)
return this.append((String)s);
if (s instanceof AbstractStringBuilder)
return this.append((AbstractStringBuilder)s);
return this.append(s, 0, s.length());
}
扩容机制
对于 StringBuffer 和 StringBuilder 的扩容机制能够只看一行代码。
int newCapacity = (value.length << 1) + 2;//value.length * 2 + 2
/**
* Returns a capacity at least as large as the given minimum capacity.
* Returns the current capacity increased by the same amount + 2 if
* that suffices.
* Will not return a capacity greater than {@code MAX_ARRAY_SIZE}
* unless the given minimum capacity is greater than that.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero or
* greater than Integer.MAX_VALUE
*/
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {newCapacity = minCapacity;}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}