StringBuffer与StringBuild底层实现与区别,及与String的本质差异

如果要进行大量的字符串拼接时,因为String类是不可变的,会在字符串当量池中产生大量的字符串对象所以并不建议采用这种方式来写。建议用StringBuffer或StringBuild。

  1. 创建一个StringBuffer
StringBuffer sb = new StringBuffer();

解析下这个构造方法,来看下源码

public StringBuffer() {
        super(16);
    }

调用了父类的方法,继续进入这个方法。

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

可以得到StringBuffer底层实际上是个char[ ] 数组。
往StringBuffer中放字符串,实际中放到char[ ]数组当中了。
StringBuffer的初始化容量是16。

  1. 解析StringBuffer的append(Object o)方法
sb.append("one");

进去append(),看下源码

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

可以看出这里是调用了父类的方法,看父类的append()方法

 public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();         //这是省略了一个大括号
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

再来看下ensureCapacityInternal(count+len)这个方法(从字面含义来看是保证容量)

 private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
    }
  void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        ***value = Arrays.copyOf(value, newCapacity);***
    }

从这段代码可以看出调用了 Arrays.copyOf(value, newCapacity)方法来扩容,(此方法已经读过,可以去之前写的看看)
str.getChars(0, len, value, count); 这段代码是执行下个复制(之前博客有讲);看下源码

 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

这是StringBuild 和StringBuffer执行原理。

  1. 与String类本质的区别是
char[] value;
 private final char value[];        //String类中的

用final来修饰的变量是不可变的,只能赋值一次,所以这才是本质的差异。

  1. StringBuild 和StringBuffer的区别
    StringBuffer中的方法都有Synchronized关键字来修饰。表示在多线环境下运行是线程安全的。StringBuild是线程不安全的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值