zoukankan      html  css  js  c++  java
  • 浅谈Java中的String、StringBuffer、StringBuilder

    看再多别人的博客都不如自己翻一下源码:

    String 内部使用final 修饰的byte[] 数组保存字符串,所以说String是不可变的。

    @Stable
    private final byte[] value;

    为什么说String相加每次都会返回新的String对象?看下源码就知道了

    字符串相加的时候先调用concat方法,最终是调用System.arraycopy这个方法把两个byte[]数组相加,在new 一个新的String对象返回,所以说每次字符串相加都会返回新的String对象。我们特别注意一下这个getBytes方法和System.arraycopy这两个方法,接下来查看StringBuffer和StringBuilder对象的时候还会说到。

    1 void getBytes(byte dst[], int dstBegin, byte coder) {
    2         if (coder() == coder) {
    3             System.arraycopy(value, 0, dst, dstBegin << coder, value.length);
    4         } else {    // this.coder == LATIN && coder == UTF16
    5             StringLatin1.inflate(value, 0, dst, dstBegin, value.length);
    6         }
    7     }
     1 public String concat(String str) {
     2         int olen = str.length();
     3         if (olen == 0) {
     4             return this;
     5         }
     6         if (coder() == str.coder()) {
     7             byte[] val = this.value;
     8             byte[] oval = str.value;
     9             int len = val.length + oval.length;
    10             byte[] buf = Arrays.copyOf(val, len);
    11             System.arraycopy(oval, 0, buf, val.length, oval.length);
    12             return new String(buf, coder);
    13         }
    14         int len = length();
    15         byte[] buf = StringUTF16.newBytesFor(len + olen);
    16         getBytes(buf, 0, UTF16);
    17         str.getBytes(buf, len, UTF16);
    18         return new String(buf, UTF16);
    19     }

    StringBuffer:继承之AbstractStringBuilder这个抽象类,这个抽象类内部使用 byte[] value;保存字符串的值,我们注意下和String的区别,String内部的byte[]数组使用了final关键字修饰。

    我们再看看下append这个方法,注意看下7行、16行、21行的代码 ,是不是和String 字符相加的方法很像?确实是的,也是通过System.arraycopy这个方法完成字符串的拼接,只不过append这个方法内部调用了ensureCapacityInternal这个方法完成了byte[]数组长度的判断和数组的扩容。

     1 public AbstractStringBuilder append(String str) {
     2         if (str == null) {
     3             return appendNull();
     4         }
     5         int len = str.length();
     6         ensureCapacityInternal(count + len);
     7         putStringAt(count, str);
     8         count += len;
     9         return this;
    10     }
    11 
    12  private final void putStringAt(int index, String str) {
    13         if (getCoder() != str.coder()) {
    14             inflate();
    15         }
    16         str.getBytes(value, index, coder);
    17     }
    18 
    19 void getBytes(byte dst[], int dstBegin, byte coder) {
    20         if (coder() == coder) {
    21             System.arraycopy(value, 0, dst, dstBegin << coder, value.length);
    22         } else {    // this.coder == LATIN && coder == UTF16
    23             StringLatin1.inflate(value, 0, dst, dstBegin, value.length);
    24         }
    25     }
    private void ensureCapacityInternal(int minimumCapacity) {
            // overflow-conscious code
            int oldCapacity = value.length >> coder;
            if (minimumCapacity - oldCapacity > 0) {
                value = Arrays.copyOf(value,
                        newCapacity(minimumCapacity) << coder);
            }
        }

    StringBuilder 和StringBuffer都是继承之AbstractStringBuilder这个抽象类他们区别就在以自身的方法,看下面的代码

    StringBuffer调用父类方法的时候使用了synchronized这个关键字来修饰,StringBuilder 直接调用父类的方法。如果我们仔细查看源代码就会发现StringBuffer的方法都使用了
    synchronized这个关键字来修饰,所以StringBuffer是线程安全的,StringBuilder是线程不安全的。
    StringBuffer比StringBuffer效率较低的原因也是因为synchronized保证了线程安全。数据完整性和效率之间本身就有矛盾,不能两者兼得。
     1 StringBuffer 的append方法
     2    @Override
     3     @HotSpotIntrinsicCandidate
     4     public synchronized StringBuffer append(String str) {
     5         toStringCache = null;
     6         super.append(str);
     7         return this;
     8     }
     9 
    10 StringBuffer 的append方法
    11 @Override
    12     @HotSpotIntrinsicCandidate
    13     public StringBuilder append(String str) {
    14         super.append(str);
    15         return this;
    16     }
  • 相关阅读:
    dota监测
    R0:前瞻
    Python基础
    c++成员函数
    异步IO简介
    使用自定义类型做qmap,qhash的key
    c++ primer 7 函数
    c++ primer 6 语句
    c++ primer 5 表达式
    c++ primer 4 数组和指针
  • 原文地址:https://www.cnblogs.com/liuyu7177/p/10499533.html
Copyright © 2011-2022 走看看