Java之StringBuilder源码分析(第一篇:创建对象)

前言

    String、StringBuilder、StringBuffer都是我们常用的字符串类,那么StringBuilder是怎么实现的字符串拼接?又是怎么实现的删除字符?值得我们深入到源码中一探究竟!

StringBuilder类结构

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
        
        …………省略很多源码………… 
   
}

    StringBuilder位于java.lang包中,直接父类是AbstractStringBuilder,实现了两个接口,一个是Serializable、另一个是CharSequence,StringBuilder不允许被继承,所以直接采用了final修饰!

AbstractStringBuilder类结构

abstract class AbstractStringBuilder implements Appendable, CharSequence {

                  ……省略很多源码……

}

    AbstractStringBuilder同样位于java.lang包中,它是个抽象类,实现了两个接口,一个是Appendable、另一个是CharSequence接口。如果你看过线程安全的StringBuffer(注意不是StringBuilder),你会知道StringBuilder与StringBuffer继承的同一个父类:AbstractStringBuilder,该父类已经写好了大部分功能,不过由于是抽象类,不能创建对象,需要由具体的子类才能产生对象,写到这里,我想你也能猜到,StringBuilder与StringBuffer功能相似,只是前者只能在单线程下使用,后者则可以在多线程使用,这是为什么呢?答案将在另一篇StringBuffer的文章中解答

StringBuilder类加载

    当我们使用StringBuilder的时候,StringBuilder类会加载到JVM中,最先执行的代码,也是类加载阶段的代码,按照继承结构,类的加载顺序如下:Object类、AbstractStringBuilder类、StringBuilder类,在类加载的时候,所有静态成员会按照书写顺序执行,Object的代码我就不说了,从AbstractStringBuilder类、StringBuilder类,执行了下面这些代码

AbstractStringBuilder的静态成员

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

常量MAX_ARRAY_SIZE的值,表示StringBuilder对象持有的数组对象的最大容量值

 StringBuilder的静态成员

    static final long serialVersionUID = 4383685877147921099L;

常量serialVersionUID表示类序列号时的版本,防止不同的类版本

StringBuilder对象的创建

    提供4个创建StringBuilder对象的构造方法,你可以根据自己的需求,选择对象的创建方式,稍后逐个分析每个构造方法,在此之前先分析创建StringBuilder对象时,哪些实例成员的代码会被执行

AbstractStringBuilder的实例成员

    char[] value;

    int count;

    AbstractStringBuilder是StringBuilder的父类,其中定义的两个实例变量会初始化,而在StringBuilder类下则没有定义其它实例变量!

value 用于保存字符的数组对象

count 表示字符的数量

StringBuilder默认构造方法分析

    public StringBuilder() {
        super(16);
    }

    显示调用父类的1个参数的构造方法,并传入值为16,表示字符数量

父类AbstractStringBuilder的单个参数构造方法分析

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

value为当前对象持有的char数组,此处新创建一个char数组对象,传入的参数capacity,表示数组对象的容量

备注:如果当前创建的是StringBuilder对象,则当前对象为StringBuilder对象,因为父类为抽象类,是不能创建对象的!

StringBuilder指定数组容量的构造方法分析

    public StringBuilder(int capacity) {
        super(capacity);
    }

    用于指定数组初始化容量的构造方法,同样调用父类AbstractStringBuilder的1个参数的构造方法

StringBuilder指定字符序列的构造方法

    public StringBuilder(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }

用于在创建StringBuilder对象时,直接添加一个字符串的方法

1、首先调用当前重载的另一个StringBuilder的构造方法,用于初始化char数组对象

2、接着调用append()方法完成字符序列的添加,将字符序列添加到字符数组对象中

append()方法分析

    @Override
    public StringBuilder append(CharSequence s) {
        super.append(s);
        return this;
    }

1、首先调用父类AbstractStringBuilder的append()方法,完成添加工作

2、向调用者返回当前对象

这个添加字符的方法,稍后会在单独文章中分析

AbstractStringBuilder中的append()方法分析

    @Override
    public AbstractStringBuilder append(CharSequence s) {
        if (s == null)
            return appendNull();
        if (s instanceof String)
            return this.append((String)s);
        if (s instanceof AbstractStringBuilder)
            return this.append((AbstractStringBuilder)s);

        return this.append(s, 0, s.length());
    }

1、检查传入的字符序列对象

如果为null,直接调用appendNull()方法,并返回

2、检查字符序列对象的实际类型是否为String

如果为String,则调用当前重载的append()方法,传入的参数会进行强制转换,将CharSequence强制转换为String对象

3、检查字符序列对象的实际类型是否为AbstractStringBuilder

如果为AbstractStringBuilder,调用重载的append()方法,注意这次类型强行转为AbstractStringBuilder

4、兜底,即不为null、也不为String、也不是AbstractStringBuilder

调用重载的append()方法,传入3个参数

5、向调用者返回当前对象

备注:注意虽然返回的AbsractStringBuilder对象,但由于抽象类不能创建对象,所以实际是子类对象

StringBuilder指定字符串的构造方法分析

    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }

    用于在创建StringBuilder对象时,并指定一个字符串

1、首先使用super调用父类AbstractStringBuidler的构造方法

此时主要是为了创建足够大的字符数组

2、添加字符串到字符数组中

使用的append()方法

总结

1、如果字符串经常改变(添加、删除、修改)当属使用StringBuilder

2、StringBuilder提供4种不同的构造方法,我们可以根据需求选择何时的构造方法创建StringBuilder对象

下篇将分析StringBuilder中的append()系列方法,用于添加字符

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值