该类是一个抽象类,表示一个可变的字符串序列。
其有两个属性,char[] value数组,以及count。
char[] value;
int count;
数组用于存储字符,count用来标记存储字符的个数。
因为通常value数组并没有存满。
无参的构造方法并没有初始化参数。
/**
* This no-arg constructor is necessary for serialization of subclasses.
*/
AbstractStringBuilder() {
}
输入参数为capacity的构造方法,设置数组的长度,并new出这个数组。
/**
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
length方法,返回字符串的长度。长度指的是value数组里面存储的字符个数,容量指的是value数组的长度,二者不一样。
/**
* Returns the length (character count).
*
* @return the length of the sequence of characters currently
* represented by this object
*/
@Override
public int length() {
return count;
}
capacity方法,返回数组长度。
/**
* Returns the current capacity. The capacity is the amount of storage
* available for newly inserted characters, beyond which an allocation
* will occur.
*
* @return the current capacity
*/
public int capacity() {
return value.length;
}
扩展容量方法,可以看出新的容量是在原容量二倍加二和输入参数中取最大值作为新的容量,如果超过int的范围,则设为int的最大值。
然后new一个新数组,将原数组的内容复制到新数组中。
/**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
*/
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
获取特定位置上的字符,和String类似
@Override
public char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
设置特定位置上的字符,直接在value数组上修改,因为数组没有用final修饰
public void setCharAt(int index, char ch) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
value[index] = ch;
}
传入参数为Object的添加方法
先把传入参数转换为String类型,再添加。
可以看出只要重写了toString方法,都可以直接添加到AbstractStringBuilder中。
/**
* Appends the string representation of the {@code Object} argument.
* <p>
* The overall effect is exactly as if the argument were converted
* to a string by the method {@link String#valueOf(Object)},
* and the characters of that string were then
* {@link #append(String) appended} to this character sequence.
*
* @param obj an {@code Object}.
* @return a reference to this object.
*/
public AbstractStringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
其中**String.valueOf()方法就是调用toString()**方法。
/**
* Returns the string representation of the {@code Object} argument.
*
* @param obj an {@code Object}.
* @return if the argument is {@code null}, then a string equal to
* {@code "null"}; otherwise, the value of
* {@code obj.toString()} is returned.
* @see java.lang.Object#toString()
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
传入参数为String的添加方法
/**
* 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;
}
值得注意的是,如果参数为null,调用appendNull方法,该方法会在字符串末尾添加null。
也就是说,传入参数为null,相当于添加一个“null”字符串。
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
ensureCapaciatyInternal方法可以检测容量是否足够存储字符,如果不够则使用expandCapacity方法扩容。`
/**
* This method has the same contract as ensureCapacity, but is
* never synchronized.
*/
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}