Java中的String、StringBuffer、StringBuilder的联系

java中最常用的跟字符串相关的类有StringStringBufferStringBuilder
因为StringBuffer和StringBuilder十分类似,所以先来看看他俩的异同:

StringBufferjdk1.0就已经有了的。
StringBuilder是在jdk1.5才加入的。

这两个类十分的类似,对字符串的操作他们两个类中都有,具体操作也大同小异。可以简单的理解成:StringBuilder是StringBuffer的扩充。

不同在于
在两者都可以使用的情况下,StringBuilder要快于StringBuffer。这也很好理解,一代更比一代强嘛。
不过最大的区别是:对于字符串的追加操作:append方法
StringBuffer是线程安全的,StringBuilder不是线程安全的。

看看java的源码就知道了:
StringBuffer中:

public synchronized StringBuffer append(char str[]) {
    super.append(str);
    return this;
}

StringBuilder中:

public StringBuilder append(char str[]) {
    super.append(str);
    return this;
}

注意StringBuffer类的append方法,他有一个关键字synchronized,表示该已经加锁。也就是说在某个线程要调用这个方法前,需要查看是否已经有其他线程在使用这个方法,如果没有则可以直接使用,如果有则需要等待其他线程使用完后才能调用。

所以,StringBuffer与StringBuilder的区别在于:
1.StringBuilder快于StringBuffer
2.StringBuffer是线程安全的,StringBuilder是线程不安全的

所以在单线程中适合使用StringBuilder,在多线程中适合使用StringBuffer

下面来看看String与StringBuilder(因为StringBuffer与StringBuilder类似,所以这里只谈StringBuilder)的联系与区别:
大家知道String的对象可以通过 + 操作符来实现字符串的追加。但具体是怎么实现的呢。
首先我们要知道一点,String类是不可变类,所以通过 + 操作符追加后的字符串一定是新生成的某一个类的对象。

如果像大牛那样懂反编译的话,通过反编译就可以看出,字符串的 + 操作实际上就是先实例化了一个StringBuilder对象,然后调用找个对象的append方法追加后再调用对象的toString方法送出去,返回给之前的字符串引用。看下面一段伪代码:

String s = "abc";
s = s + "xyz";

等同于:

StringBuilder sb = new StringBuilder (s);
sb.append("xyz");
s = sb.toString();

也许有人会问,既然这样,岂不是两者完全一样了。先不说一不一样,我们带着这个疑问,思考一个问题:
加入我想在循环中追加字符串,我应该怎么操作?:

String s = "abc";
for(i = 0;i < 100;i ++){
    s += "abc";
}

按照前面的说法,在for循环中会发生100次实例化对象的操作,虽然JVM有垃圾回收机制,但是这毕竟也需要时间和资源的耗费。再看看下面一个:

StringBuilder sb = new StringBuilder ("abc");
for(i = 0;i < 100;i ++){
    sb.append("abc");
}

这样操作的话就是在一个StringBuilder对象的基础上一次次追加而不会增加新的对象,性能会有很大提高,也会很节省资源。

所以,String与Stringbuilder区别在于:
在处理数据量小的时候适合使用String的 + 操作,在数据量大的时候适合使用StringBuilder对象。

原文地址:https://www.cnblogs.com/lipijin/p/3089695.html