string,StringBuffer和StringBuilder区别(带源码)

   日期:2020-07-13     浏览:92    评论:0    
核心提示:很多小伙伴经常使用到string,stringBuffer和StringBuilder,但对他们之间的区别却是很难说的上来。今天我将着手从源码和内存分析这两个层面来解说一下他们之间的区别。下面开始上代码: String str = aaa; String str1 = new String(sdf); StringBuilder stringBuilder = new StringBuilder(str); StringBuffer stringBuffer

很多小伙伴经常使用到string,stringBuffer和StringBuilder,但对他们之间的区别却是很难说的上来。今天我将着手从源码和内存分析这两个层面来解说一下他们之间的区别。
下面开始上代码:

		String str = "aaa";
		String str1 = new String("sdf");
        StringBuilder stringBuilder = new StringBuilder(str);
        StringBuffer stringBuffer = new StringBuffer(str);

从这段代码可以看出他们之间对象名就有着不同(手动狗头),下面我们进入他们的源码来分别看一下他们之间的不同。
string源码:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
    private final char value[];

    
    private int hash; // Default to 0
    public String() {
        this.value = "".value;
    }

    
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

从上面这段代码中我们可以看到string不管是空参构造还是有参构造都使用了value这个属性,在看value的属性定义private final char value[]; 竟然是一个常量数组。这意味着char数组长度不可改变,同样也意味着string的内容是不可修改的。在需要修改string内容时,只能通过在开辟新的堆内存,然后把两个堆内存的内容,在一个新建的内存中拼接。这将会产生大量的垃圾空间,使性能下降。在少量操作数据时可以使用(因为简单)。了解了这个我们来看下一个,StringBuilder继续上源码:

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    
    static final long serialVersionUID = 4383685877147921099L;

    
    public StringBuilder() {
        super(16);
    }

    
    public StringBuilder(int capacity) {
        super(capacity);
    }

    
    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }
     @Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

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

    
    public StringBuilder append(StringBuffer sb) {
        super.append(sb);
        return this;
    }

    @Override
    public StringBuilder append(CharSequence s) {
        super.append(s);
        return this;
    }

上面这段源码无法看出StringBuilder的属性是否是常量,构造方法也只是使用了它父类的构造,那么就看它继承的AbstractStringBuilder的代码。但可以看出StringBuilder的方法上没有线程安全处理,这意味着StringBuilder在多线程环境下是不安全的,但在单线程环境下效率高,可以在同一堆内存修改字符串的值,不会产生多余的垃圾空间。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    
    char[] value;

    
    int count;

    
    AbstractStringBuilder() {
    }

    
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

从这段代码中我们可以看到AbstractStringBuilder的构造方法使用的属性value,不是常量数组,这意味着char数组长度可改变,同样也意味着AbstractStringBuilder的内容是可修改的,那么继承它构造的StringBuilder的内容也是可以修改的。接下来看StringBuffer,源码如下:

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    
    private transient char[] toStringCache;

    
    static final long serialVersionUID = 3388685877147921107L;

    
    public StringBuffer() {
        super(16);
    }

    
    public StringBuffer(int capacity) {
        super(capacity);
    }
     @Override
    public synchronized int length() {
        return count;
    }

    @Override
    public synchronized int capacity() {
        return value.length;
    }


    @Override
    public synchronized void ensureCapacity(int minimumCapacity) {
        super.ensureCapacity(minimumCapacity);
    }

    
    @Override
    public synchronized void trimToSize() {
        super.trimToSize();
    }

    
    @Override
    public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }

StringBuffer构造方法同样使用了它父类AbstractStringBuilder的构造,同时可以看出StringBuffer的方法上都有线程安全处理,这意味着StringBuffer在多线程环境下是安全的,但在单线程环境下效率相对StringBuilder要低很多,同样可以在同一堆内存修改字符串的值,同样不会产生多余的垃圾空间。

总结一下:
String: 值不可修改,多线程环境下,线程安全(final修饰),字符串拼接效率低(少量数据可用)
StringBuffer值可修改,多线程环境下,线程安全(synchronized修饰每个方法),单线程环境字符串拼接效率低
StringBuilder值可修改,多线程环境下,不线程安全,单线程环境字符串拼接效率高

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服