从源码深入分析Java中 StringBuffer和StringBuilder的区别

从源码深入分析Java中 StringBuffer和StringBuilder的区别?

  • StringBuffer和StringBuilder都继承自抽象类AbstractStringBuilder。
  • 存储数据的字符数组没有被final修饰,说明值可以改变,抽象类AbstractStringBuilder内部都提供了一个自动扩容机制,当发现长度不够的时候(初始默认长度是16),会自动进行扩容工作,扩展为原数组长度的2倍加2,创建一个新的数组,并将数组的数据复制到新数组,所以对于拼接字符串效率要比String要高。
  • 线程安全性:StringBuffer由于很多方法都被 synchronized 修饰了所以线程安全,但是当多线程访问时,加锁和释放锁的过程很平凡,所以效率相比StringBuilder要低。StringBuilder相反执行效率高,但是线程不安全。
  • 执行速度:StringBuilder > StringBuffer > String。

1. 继承关系分析

StringBuffer和StringBuiler都继承自AbstractStringBuilder类,JDK1.7源码如下:

/**StringBuffer类源码*/
public final class StringBuffer extends AbstractStringBuilder
    implements Serializable, CharSequence

/**StringBuilder类源码*/
public final class StringBuilder extends AbstractStringBuilder
    implements Serializable, CharSequence

/**AbstractStringBuilder类源码*/
abstract class AbstractStringBuilder
    implements Appendable, CharSequence

2. 动态实现扩容分析

StringBuffer的构造方法,JDK1.7源码如下:

	/**默认长度是16*/
    public StringBuffer()
    {
        super(16);
    }
	/**可以指定初始长度*/
    public StringBuffer(int i)
    {
        super(i);
    }
	/**变量长度+16*/
    public StringBuffer(String s)
    {
        super(s.length() + 16);
        append(s);
    }
	/**变量长度+16*/
    public StringBuffer(CharSequence charsequence)
    {
        this(charsequence.length() + 16);
        append(charsequence);
    }

StringBuiler的构造方法,JDK1.7源码如下:

	/**默认长度是16*/
    public StringBuilder()
    {
        super(16);
    }
	/**可以指定初始长度*/
    public StringBuilder(int i)
    {
        super(i);
    }
	/**变量长度+16*/
    public StringBuilder(String s)
    {
        super(s.length() + 16);
        append(s);
    }
	/**变量长度+16*/
    public StringBuilder(CharSequence charsequence)
    {
        this(charsequence.length() + 16);
        append(charsequence);
    }

抽象类AbstractStringBuilder扩容机制,JDK1.7源码如下:

    public void ensureCapacity(int i)
    {
        if(i > 0)
            ensureCapacityInternal(i);
    }

    private void ensureCapacityInternal(int i)
    {
        if(i - value.length > 0)
            expandCapacity(i);
    }

    void expandCapacity(int i)
    {
    	//扩展长度j = 为原数组长度的2倍加2
        int j = value.length * 2 + 2;
        if(j - i < 0)
            j = i;
        if(j < 0)
        {
        	//注意:这里可能会溢出,溢出后是负数,
            if(i < 0)
                throw new OutOfMemoryError();
            j = 2147483647;
        }
        value = Arrays.copyOf(value, j);
    }

由抽象类AbstractStringBuilder可知:StringBuffer和StringBuiler的扩容的机制在抽象类AbstractStringBuilder中实现,当发现长度不够的时候(默认长度是16),会自动进行扩容工作,扩展为原数组长度的2倍加2,创建一个新的数组,并将数组的数据复制到新数组。

3. 线程安全性分析

StringBuffer的相关方法,JDK1.7源码如下:

    public synchronized StringBuffer append(Object obj)
    {
        super.append(String.valueOf(obj));
        return this;
    }
    public synchronized String substring(int i, int j)
    {
        return super.substring(i, j);
    }
    public synchronized StringBuffer replace(int i, int j, String s)
    {
        super.replace(i, j, s);
        return this;
    }
    public synchronized StringBuffer delete(int i, int j)
    {
        super.delete(i, j);
        return this;
    }
    public synchronized int length()
    {
        return count;
    }

StringBuiler的相关方法,JDK1.7源码如下:

    public StringBuilder append(Object obj)
    {
        return append(String.valueOf(obj));
    }
    public StringBuilder replace(int i, int j, String s)
    {
        super.replace(i, j, s);
        return this;
    }
    public StringBuilder delete(int i, int j)
    {
        super.delete(i, j);
        return this;
    }
    public volatile int length()
    {
        return super.length();
    }

由源码中我们可知:

  • StringBuffer几乎都是调用的父类的方法而且都加了synchronized修饰,所以是线程安全的;但是平凡的加锁和释放锁导致性能降低,执行速度上比StringBuffer要慢。
  • StringBuilder所有方法都没有用synchronized关键字修饰,所以线程不安全,但是由于没有加锁释放锁导的过程,执行速度上比StringBuffer要快。

……
帮助他人,快乐自己,最后,感谢您的阅读!
所以如有纰漏或者建议,还请读者朋友们在评论区不吝指出!
……
个人网站…知识是一种宝贵的资源和财富,益发掘,更益分享…

  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaStringBufferStringBuilder类是用于字符串操作的可变字符序列类。它们都具有类似的功能,但在某些方面有所不同。StringBuffer是线程安全的,适用于多线程环境下的字符串拼接和修改操作。而StringBuilder是非线程安全的,适用于单线程环境下的字符串操作,它的性能相对较高。 StringBufferStringBuilder类都提供了类似的方法,包括创建、追加、插入、删除、替换、反转等操作。可以使用append()方法在字符串末尾追加内容,使用insert()方法在指定位置插入内容,使用delete()方法删除指定位置的字符,使用replace()方法替换指定范围内的字符,使用reverse()方法反转字符串等。此外,它们还支持toString()方法将可变字符序列转换为字符串,以及length()方法获取字符序列的长度等常见操作。 在使用StringBufferStringBuilder类时,需要根据实际情况选择合适的类。如果在多线程环境下进行字符串操作,安全性是首要考虑因素,可以使用StringBuffer类。如果在单线程环境下进行字符串操作,并且对性能有较高要求,可以使用StringBuilder类。 总之,JavaStringBufferStringBuilder类提供了灵活和高效的字符串操作方法,可以根据需要选择合适的类来处理字符串。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Java StringBufferStringBuilder](https://blog.csdn.net/sheng0113/article/details/124081818)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [面试题java StringBufferStringBuilder类常见操作和用法](https://download.csdn.net/download/qq_43797491/87906515)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值