StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String 类型和 StringBuffer 、StringBuilder 类型的主要性能区别其实在于 String 是不可变的对象,而后俩者都是可变的。
来看看 StringBuffer类源码定义:
上例代码我们发现 StringBuffer 继承了 AbstractStringBuilder抽象类。包括构造方法的实现,都是父类提供的。
然后,我们打开 StringBuilder源码定义:
我们发现两者都继承了AbstractStringBuilder抽象类。且构造方法都调用父类实现。
我们接着看两者append方法实现:
先看StringBuffer的:
再看StringBuilder的:
对比上面两段源码 我们发现 StirngBuffer 和StringBuilder的 append实现都是调用父类实现的。唯一不同的是 StringBuffer是线程安全的,方法中多了synchronized ,而StringBuilder 是非线程安全的。
我们看下父类AbstractStringBuilder 定义 及 append 实现:
StringBuilder 字符串变量(非线程安全)
String 类型和 StringBuffer 、StringBuilder 类型的主要性能区别其实在于 String 是不可变的对象,而后俩者都是可变的。
来看看 StringBuffer类源码定义:
- public final class StringBuffer
- extends AbstractStringBuilder
- implements java.io.Serializable, CharSequence
- {
- public StringBuffer() {
- super(16);
- }
- public StringBuffer(int capacity) {
- super(capacity);
- }
上例代码我们发现 StringBuffer 继承了 AbstractStringBuilder抽象类。包括构造方法的实现,都是父类提供的。
然后,我们打开 StringBuilder源码定义:
- public final class StringBuilder
- extends AbstractStringBuilder
- implements java.io.Serializable, CharSequence
- {
- public StringBuilder() {
- super(16);
- }
- public StringBuilder(int capacity) {
- super(capacity);
- }
我们发现两者都继承了AbstractStringBuilder抽象类。且构造方法都调用父类实现。
我们接着看两者append方法实现:
先看StringBuffer的:
- public synchronized StringBuffer append(Object obj) {
- super.append(String.valueOf(obj));
- return this;
- }
- public synchronized StringBuffer append(String str) {
- super.append(str);
- return this;
- }
- //...
再看StringBuilder的:
- public StringBuilder append(Object obj) {
- return append(String.valueOf(obj));
- }
- public StringBuilder append(String str) {
- super.append(str);
- return this;
- }
- //...
对比上面两段源码 我们发现 StirngBuffer 和StringBuilder的 append实现都是调用父类实现的。唯一不同的是 StringBuffer是线程安全的,方法中多了synchronized ,而StringBuilder 是非线程安全的。
我们看下父类AbstractStringBuilder 定义 及 append 实现:
- abstract class AbstractStringBuilder implements Appendable, CharSequence {
- //底层与String类一样都是 char类型数组。
- char value[];
- //字符串长度
- int count;
- AbstractStringBuilder() {
- }
- AbstractStringBuilder(int capacity) {
- value = new char[capacity];
- }
- public AbstractStringBuilder append(Object obj) {
- return append(String.valueOf(obj));
- }
- public AbstractStringBuilder append(String str) {
- //对于str==null的
- if (str == null) str = "null";
- int len = str.length();
- if (len == 0) return this;
- //新的字符串长度
- int newCount = count + len;
- if (newCount > value.length)
- //当新的字符串长度比原先数组长度大时,需要对char 数组扩容。
- expandCapacity(newCount);
- //将新添的数据追加到char类型数组中。
- str.getChars(0, len, value, count);
- count = newCount;
- return this;
- }
- //数组扩容
- void expandCapacity(int minimumCapacity) {
- //先扩容成 (原先的长度+1)*2
- int newCapacity = (value.length + 1) * 2;
- //判断newCapacity值是否满足要求
- //如果新的长度还是不够,则直接取值 minimumCapacity
- if (newCapacity < 0) {
- newCapacity = Integer.MAX_VALUE;
- } else if (minimumCapacity > newCapacity) {
- newCapacity = minimumCapacity;
- }
- char newValue[] = new char[newCapacity];
- //将原先的数据拷贝到新的char 数组中。
- System.arraycopy(value, 0, newValue, 0, count);
- value = newValue;
- }
- public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
- if (srcBegin < 0) {
- throw new StringIndexOutOfBoundsException(srcBegin);
- }
- if (srcEnd > count) {
- throw new StringIndexOutOfBoundsException(srcEnd);
- }
- if (srcBegin > srcEnd) {
- throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
- }
- System.arraycopy(value, offset + srcBegin, dst, dstBegin,
- srcEnd - srcBegin);
- }