这篇文章主要讲解了String、StringBuilder、StringBuffer的区别,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。
创新互联公司-专业网站定制、快速模板网站建设、高性价比双流网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式双流网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖双流地区。费用合理售后完善,十载实体公司更值得信赖。
StringBuilder、StringBuffer 和 String 一样,都是用于存储字符串的。
1、那既然有了 String ,为什么还需要他们两个呢?
原因是 String 是不可变的,它每次的字符串拼接,实际上都会 new 一个新的 String 进行接收。
2、谈谈StringBuilder、StringBuffer他们两个的联系:
我们可以知道 StringBuffer 在 1.0 的时候就发布了,那为什么还需要 StringBuilder 呢?原因是它的大部分方法都上了锁,是线程安全的,导致了效率较低!而我们有时候不需要考虑线程安全问题,追求效率!所以 StringBuilder 在 1.5 的时候就出来了!
3、StringBuilder、StringBuffer 的异同:*
不同:
- StringBuffer 它因为追求安全,给大量方法上锁,线程安全!
- StringBuilder 它因为追求效率,没有给方法上锁,线程不安全!
相同:内部方法和 StringBuffer 完全一致,因为都继承了 AbstractStringBuilder,底层数组都是用父类的。
4、源码浅析 String:

结论:final 修饰了底层的字符数组,故内容不可变。
5、源码浅析 StringBuilder:构造方法
观察构造方法:
 public StringBuilder() {
    super(16);
  }
  
  public StringBuilder(int capacity) {
    super(capacity);
  }
  public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
  }
  public StringBuilder(CharSequence seq) {
    this(seq.length() + 16);
    append(seq);
  }结论:可以看出,它有一个默认的长度 16!而当传入参数是一个字符或者字符串时,它也会自动的传入参数的长度上加上 16!
6、源码浅析 StringBuilder:append 方法
 @Override
  public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
  }
  @Override
  public StringBuilder append(String str) {
    super.append(str);
    return this;
  }我们发现,它还是调用的父类的 append 方法,说明这个方法他并没有重写,那么 StringBuffer 也一样!
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;
  }结论:我们可以看出,他也是可以拼接 null 的!
 private AbstractStringBuilder appendNull() {
    int c = count;
    ensureCapacityInternal(c + 4);
    final char[] value = this.value;
    value[c++] = 'n';
    value[c++] = 'u';
    value[c++] = 'l';
    value[c++] = 'l';
    count = c;
    return this;
  }然后观察,它接着进行了一个数组容量的判断,而数组的扩容,其实就是在里面实现的,我们点进去看一下!
 private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    if (minimumCapacity - value.length > 0) {
      value = Arrays.copyOf(value,
          newCapacity(minimumCapacity));
    }
  }结论:它先是判断,当前数组容量+拼接字符 是否大于 数组长度,如果大于,则进行数组拷贝,并将底层数组的引用指向新数组!
private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int newCapacity = (value.length << 1) + 2;
    if (newCapacity - minCapacity < 0) {
      newCapacity = minCapacity;
    }
    return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
      ? hugeCapacity(minCapacity)
      : newCapacity;
  }结论:由此可见,新数组长度扩容为原数组的2倍+2 !
问题:那它究竟是怎么拼接字符串的呢?
sb.getChars(0, len, value, count);
进去看一下:String 的 getChars 方法
 public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
  {
    if (srcBegin < 0)
      throw new StringIndexOutOfBoundsException(srcBegin);
    if ((srcEnd < 0) || (srcEnd > count))
      throw new StringIndexOutOfBoundsException(srcEnd);
    if (srcBegin > srcEnd)
      throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
    System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
  }实际调用了一个系统类方法:arraycopy,再点进去看一下!
 public static native void arraycopy(Object src, int srcPos,
                    Object dest, int destPos,
                    int length);结论:底层最终是调用的本地方法,实现了的字符数组拷贝,但由于本地方法是可以和操作系统直接打交道的,所以它的 append 字符串拼接效率会高于 String!
看完上述内容,是不是对String、StringBuilder、StringBuffer的区别有进一步的了解,如果还想学习更多内容,欢迎关注创新互联行业资讯频道。
网站标题:String、StringBuilder、StringBuffer的区别
标题链接:http://www.scyingshan.cn/article/jodehh.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 