The Apache Harmony implementation relies on the methods in AbstractStringBuilder
to manage additions/deletions (StringBuffer extends AbstractStringBuilder
).
AbstractStringBuilder
keeps a character buffer (that is, an array of char
s) to hold the current "string". When appending the next string representation of any object to this buffer it checks if the buffer contains enough space, and if there's not enough space it allocates a new character buffer, copies the old buffer, and then adds the new string to that buffer. We can glean that from the internals of enlargeBuffer
:
private void enlargeBuffer(int min) {
int newSize = ((value.length >> 1) + value.length) + 2;
char[] newData = new char[min > newSize ? min : newSize];
System.arraycopy(value, 0, newData, 0, count);
value = newData;
shared = false;
}
...and this method is invoked in any append method when the capacity of value
(the private member that holds the char buffer) would be exceeded:
final void append0(char chars[]) {
int newSize = count + chars.length;
if (newSize > value.length) {
enlargeBuffer(newSize);
}
System.arraycopy(chars, 0, value, count, chars.length);
count = newSize;
}
The standard OpenJDK implementation is pretty similar. Again, StringBuffer relies on AbstractStringBuilder:
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);
}
Note that Arrays.copyOf
copies the character array value
padding it with null characters to have total size newCapacity
, which is basically equivalent to the new char[...]
call in the Harmony approach. Again, similarly, the expandCapacity
method is invoked when there's not enough space to add the next string segment:
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;
}