Java中String,StringBuffer与StringBuilder的区别

一、String是字符串常量,对象不可变。StringBuffer与 StringBuilder是字符串变量,对象可变。

先来看String的字符串拼接代码:

String A = "aaa";
System.out.println(A);
A = "bbb";
System.out.println(A);

//输出结果:
//aaa
//bbb

看到上面的结果就奇怪了,不是说String不可变吗,怎么从"aaa"变成"bbb"了?

其实你看到的只是表象,其实第一个"aaa"和"bbb"已经不是同一个对象,"bbb"对象是重新生成的新对象,只不过之前引用A是指向对象"aaa"的,后来指向了对象"bbb",而"aaa"由于没有被引用,被JVM回收了。

所以看上去像是一个对象被修改了,而事实上是完全不同的两个对象。

再来看StringBuffer和StringBuilder的拼接代码:

StringBuffer str = new StringBuffer();
str.append("aaa");
str.append("bbb");
System.out.println(str.toString());

//输出结果:
//aaabbb
StringBuilder str = new StringBuilder();
str.append("aaa");
str.append("bbb");
System.out.println(str.toString());

//输出结果:
//aaabbb

可以看出,StringBuffer和StringBuilder都是使用append方法来进行拼接,他们的操作都是在一个对象上完成的。

二、StringBuffer是线程安全的,StringBuilder是线程不安全的。

下面这是StringBuffer源码片段,StringBuffer在几乎所有的方法上都加了synchronized加锁,这样就能保证多线程并发操作下的线程安全。

//StringBuffer源码片段
@Override
public synchronized StringBuffer append(Object obj) {
    toStringCache = null;
    super.append(String.valueOf(obj));
    return this;
}

@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

再来看StringBuilder的源码,同样的append操作,StringBuilder并没有加锁,所以StringBuilder是非线程安全的。

//StringBuildera源码片段
@Override
public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

三、执行速度不同。StringBuilder > StringBuffer > String

1、String 每次进行修改操作都会新建对象,对于JVM是一种负担,耗时耗力,特别在大量拼接的情况下,尤为明显。所以三者中String最慢。

2、StringBuffer为了能保证线程安全,在其每个方法都用synchronized加锁,加锁和释放锁本身就会消耗系统资源,所以论速度,StringBuffer不及StringBuilder。

3、StringBuilder操作不需要加锁,也不会产出多个对象拼接,所以StringBuilder速度是最快的。

四、如何选用

1、String操作简单,代码量小,适合在简单字符串操作中使用。

2、StringBuffer适合在多线程情况下使用,保证线程安全。

3、在单线程情况下,对于复杂的字符串操作,StringBuiler是很不错的选择。

猜你喜欢

转载自blog.csdn.net/qq_30745307/article/details/81207722