StringBuilder源码分析

#StringBuilder源码分析


wevan youngxhui

一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

1
2
3
    public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

可以看到StringBuilder继承了

  1. Serializable:可以序列化的标志。
  2. CharSequence接口:包含了charAt()、length() 、subSequence()、toString()这几个方法,String类也实现了这个接口。
  3. 抽象类AbstractStringBuilder,这个类封装了StringBuilder和StringBuffer大部分操作的实现

这个接口是代表一个有序字符集合,使用该接口的方法一共有四个:CharBufferStringStringBufferStringBuilder

变量及构造方法

1
2
3
4
5
6
    char[] value;
    int count;
    AbstractStringBuilder() {}
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

AbstractStringBuilder内部用一个char[]数组保存字符串,可以在构造的时候指定初始容量方法。


1
2
3
4
5
6
7
8
9
    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;
    }

append()方法用于追加字符,如果str是null,则会调用appendNull()方法。这个方法其实是追加了’n’、‘u’、’l’、’l’这几个字符。如果不是null,则首先扩容,然后调用String的getChars()方法将str追加到value末尾。最后返回对象本身,所以append()可以连续调用。


这个构造器的作用是构造一个初始化不带参数的,初始化字节为16字节。

构造一个其中不带字符的字符串生成器,初始容量由传入的 int 值指定。

构造一个字符串生成器,并初始化为指定的字符串内容。该字符串生成器的初始容量为 16 加上字符串参数的长度。

1
2
3
4
public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }

如果传入的字符串问 null 则会抛出空指针 NullPointerException 异常。

示例代码

1
2
3
4
5
6
7
8
public class StringBuilderApi {
    public static void main(String[] args) {
        String str=null;
        StringBuilder stringBuilder=new StringBuilder(str);
        System.out.println(stringBuilder);

    }
}

输出结果

Exception in thread “main” java.lang.NullPointerException at java.lang.StringBuilder.(StringBuilder.java:112) at StringBuilderApi.main(StringBuilderApi.java:7) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

构造一个字符串生成器,包含与指定的 CharSequence 相同的字符。该字符串生成器的初始容量为 16 加上 CharSequence 参数的长度。


该方法一共用13个重载函数,用于实现不同的数据类型。Object,String,StringBuffer,CharSequence,char[],boolen,int ,long,float,double 等,但是他们的作用是一直的。那就是将参数添加到字符串中。

1
2
3
4
5
6
7
8
    public StringBuilder append(String str) {
    super.append(str);
    return this;
    }
    public StringBuilder append(CharSequence s) {
    super.append(s);
    return this;
    }

Stringbulider的appen()方法显然直接调用的父类AbstractStringBuilder中的该方法。


该方法是附加一个Uncode字符在字符串末尾。

1
2
3
4
5
6
7
8
 /**
     * @since 1.5
     */
    @Override
    public StringBuilder appendCodePoint(int codePoint) {
        super.appendCodePoint(codePoint);
        return this;
    }

该方法是删除所字符串中的字符,所传入的参数为其实点和结束点。直接使用父类(AbstractStringBuilder)的方法

1
2
3
4
5
6
7
8
 /**
     * @throws StringIndexOutOfBoundsException {@inheritDoc}
     */
    @Override
    public StringBuilder delete(int start, int end) {
        super.delete(start, end);
        return this;
    }

toString()方法返回了一个新的String对象,与原来的对象不共享内存。

1
2
3
4
    public String toString() {
    // Create a copy, don't share the array
         return new String(value, 0, count);
    }

replace 方法仍旧继承了父类的 replace 方法,是替换字符

1
2
3
4
     public StringBuilder replace(int start, int end, String str) {
            super.replace(start, end, str);
            return this;
        }

该方法是插入字符串。该方法重载了12个方法。

该类所有的方法都是通过父类( AbstractStringBuilder )来实现。该方法与StringStringBuffer的区别在于,String是不可修改的,StringBufferStringBuilder是可以修改的,但是StringBuffer是线程安全的,StringBuilder是线程不安全的,但是在效率上, StringBuffer 因为对方法做了同步,所以一般是低于 StringBuilder的.

相关内容