String、StringBuffer、StringBuilder的区别和关系

String、StringBuffer、StringBuilder的区别和关系

String声明后是一个常量,而StringbufferStringBuilder是数据结构是变量,所以比String在连接字符时效率高。

并且StringBuffer和StringBuilder的区别是StringBuffer是线程安全的(synchronized) ,而StringBuilder是非线程安全的,所以速度大致排行为:StringBuilder>StringBuffer>String

以上只是基于印象或者说是死记硬背的东西,没有看源码是否真的是这样的。下面就来看看String,StringBuilder,StringBuffer的源码来真正的记住。

String

String中的concat方法实现了字符串的拼接。

实例变量

String类中有两个实例变量,分别为value和hash

1
2
3
4
5
/** The value is used for character storage. */
private final char value[];

/** Cache the hash code for the string */
private int hash; // Default to 0

构造方法

String的构造方法很多,但是都比较简单,下面来说比较常用的几种。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 当新建一个String对象的时候,会默认付一个空的字符序列,请注意,由于字符串是不可变的,因此不必使用此构造函数
public String() {
this.value = "".value;
}
// 这个构造方法,会默认新建一个值为original的字符串。同上,如果字符串不可变的,就没必要这样声明。
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
// 使用copyof方法用来复制一个新的字符数组,后续修改字符数组,不会影响到新建的字符串
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}

concat方法

为什么说String的效率低,就体现在concat拼接字符串的时候每次都要返回一个新的String对象。

1
2
3
4
5
6
7
8
9
10
11
 public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
// 返回一个新建的String对象
return new String(buf, true);
}

StringBuilder

StringBuilder继承了AbstractStringBuilder,其中的实例变量和String中的基本相同,

构造方法

1
2
3
4
5
6
7
public StringBuilder(int capacity) {
super(capacity);
}
// 调用父类的构造方法
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}

append方法

可以看到,并没有新建对象,只是在改变对象中的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public StringBuilder append(String str) {
super.append(str);
return this;
}
// append调用的还是父类的append方法
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
// 把value扩容后再把str加进去
count += len;
return this;
}

StringBuffer

和StringBuilder一样,也是继承了AbstractStringBuilder类,但是看一个append这个方法的源码就能够知道有什么区别了

append方法

添加了synchronized关键字,使得变为线程安全的,但是代价就是效率不如StringBuilder高。

1
2
3
4
5
6
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
-------------本文结束感谢您的阅读-------------

本文标题:String、StringBuffer、StringBuilder的区别和关系

文章作者:NanYin

发布时间:2018年11月08日 - 22:11

最后更新:2019年08月12日 - 13:08

原始链接:https://nanyiniu.github.io/2018/11/09/2018-11-08-String%E5%92%8CStringBuffer%E5%92%8CStringBuilder%E7%9A%84%E8%81%94%E7%B3%BB%E5%92%8C%E5%8C%BA%E5%88%AB/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。