(源码查看记录 一) String 与 StringBuffer 与 StringBuilder

(源码查看记录 一) String 与 StringBuffer 与 StringBuilder

“他们三者之间的区别”这个问题已经被问烦了,问题的答案也在网上到处可以搜索到,简单概括一下:

  • 1 对象的创建

String对象的创建和赋值必然会新建一个String对象,字符串的拼接也遵守这个规则;
StringBulider和StringBuffer只会创建一个对象,最后通过toString方法输出。

原因:在class文件被JVM装载到内存中时,JVM会创建一块缓冲池,用来存放代码中的字符串本身,而声明的变量只是一个对字符串本身的引用对象,如果对同一个声明的字符串变量进行赋值,则这个变量的引用就会发生改变,就会创建创建出新的引用对象。所以,String的拼接等操作,即使声明的变量名不改变,但实际上他对应的对象已经是一个新的对象。顺带一提,在JVM将字符串加载到缓冲池中后,后面的字符串对象会先去找已经存在的字符串,如果存在直接引用,若不存在则将其添加在缓冲池中。

  • 2 线程安全

StringBuffer线程安全,String、StringBulider非线程安全。

原因:线程是否安全决定于此变量是否允许同步,通过以下源码可以一目了然:

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

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

  • 3 执行速度

StringBulider > StringBuffer > String

原因:String的拼接等操作一定涉及了众多对象的创建,所以最慢;StringBuffer不允许同步操作,势必存在线程等待,所以第二慢。

  • 4 结论

上述原因都建立在大量字符串操作的条件上,只是new 一个字符串完全没必要考虑这么多。局部变量基本不用考虑线程安全的问题,所以尽量使用StrngBulider。

源码总结(仅作为阅读笔记,内容可能存在错漏)

主要侧重在 StringBuffer 与 StringBulider 上。

1 父类及接口

共同继承父类:AbstractStringBuilder.java;

共同实现接口:java.io.Serializable 、 CharSequence 。

java.io.Serializable 为标记序列化的接口,不做阐述。

2 接口CharSequence

2.1 CharSequence subSequence(int start, int end);

里面定义了字符串常用的一些方法,其中的 CharSequence subSequence(int start, int end) 方法引起我的注意。这个方法本身是用来做字符串截取的,与 subString() 方法是同样的效果,这是返回类型不一样。趁此机会看一下源码的实现。

//AbstractStringBuilder.java
    char[] value;
    @Override
    public CharSequence subSequence(int start, int end) {
        return substring(start, end);
    }

    public String substring(int start, int end) {
        if (start < 0)
            throw new StringIndexOutOfBoundsException(start);
        if (end > count)
            throw new StringIndexOutOfBoundsException(end);
        if (start > end)
            throw new StringIndexOutOfBoundsException(end - start);
        return new String(value, start, end - start);
    }

//String.java
    public CharSequence subSequence(int beginIndex, int endIndex) {
        return this.substring(beginIndex, endIndex);
    }

    public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

    public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
                this.value = "".value;
                return;
            }
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }

**结论 😗*subSequence方法只是调用了subString方法,返回类型不同而已。

2.2 IntStream codePoints();

codePointAt的返回值是Unicode码构成的返回值。

3 其他

StringBulider 和 StringBuffer 的容量有16字节的缓冲

//StringBulider.java
    public StringBuilder() {
        super(16);
    }
    public StringBuilder(int capacity) {
        super(capacity);
    }
    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }

//StringBuffer.java
    public StringBuffer() {
        super(16);
    }
    public StringBuffer(int capacity) {
        super(capacity);
    }
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值