如果要进行大量的字符串拼接时,因为String类是不可变的,会在字符串当量池中产生大量的字符串对象所以并不建议采用这种方式来写。建议用StringBuffer或StringBuild。
- 创建一个StringBuffer
StringBuffer sb = new StringBuffer();
解析下这个构造方法,来看下源码
public StringBuffer() {
super(16);
}
调用了父类的方法,继续进入这个方法。
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
// char[] value;
可以得到StringBuffer底层实际上是个char[ ] 数组。
往StringBuffer中放字符串,实际中放到char[ ]数组当中了。
StringBuffer的初始化容量是16。
- 解析StringBuffer的append(Object o)方法
sb.append("one");
进去append(),看下源码
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
可以看出这里是调用了父类的方法,看父类的append()方法
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;
}
再来看下ensureCapacityInternal(count+len)这个方法(从字面含义来看是保证容量)
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
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);***
}
从这段代码可以看出调用了 Arrays.copyOf(value, newCapacity)方法来扩容,(此方法已经读过,可以去之前写的看看)
str.getChars(0, len, value, count); 这段代码是执行下个复制(之前博客有讲);看下源码
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
这是StringBuild 和StringBuffer执行原理。
- 与String类本质的区别是
char[] value;
private final char value[]; //String类中的
用final来修饰的变量是不可变的,只能赋值一次,所以这才是本质的差异。
- StringBuild 和StringBuffer的区别
StringBuffer中的方法都有Synchronized关键字来修饰。表示在多线环境下运行是线程安全的。StringBuild是线程不安全的。