String源码解析

1.类的继承关系

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence

1.1 String被final修饰,所以String不能被继承,String的底层是字符数组,也是被final修饰的,也保证了String的不可变。

1.2 实现CharSequence(字符串)接口,只有几个通用的方法。

1.3 实现了Comparable,说明String是可比较的。

1.4 Serializable序列化。

2.成员变量

/** 底层数据结构,用来存储String的值 */
private final char value[];

/** 缓存String的hash值 */
private int hash; // 默认是0

/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;

/**
 * 存储对象的序列化信息
 */
private static final ObjectStreamField[] serialPersistentFields =
    new ObjectStreamField[0];

3.构造方法

/** 无参构造,初始化数组的值为空串 */
public String() {
    this.value = "".value;
}
/** 示例 */
String str = new String();//创建了一个空串对象
str = "hello";//创建了hello对象,把引用给str
//所以上述方式创建了两个对象

​
​
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}
/** 示例 */
String str = new String("hello");
//如果常量池里已经有hello,这种初始化方式只创建一个对象,否则创建两个对象
public String(char value[]) {
    //字符串数组初始化,把数组的值拷贝到value里
    this.value = Arrays.copyOf(value, value.length);
}

还有一些其他不常使用的构造方法:

public String(char value[], int offset, int count)
public String(int[] codePoints, int offset, int count)
public String(byte bytes[], int offset, int length, String charsetName)
public String(byte bytes[], int offset, int length, Charset charset)
public String(byte bytes[], String charsetName)
public String(byte bytes[], Charset charset)
public String(byte bytes[], int offset, int length)
public String(byte bytes[])
public String(StringBuffer buffer)
public String(StringBuilder builder)

4.equals方法

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

4.1 第一部分的==判断,两个对象的地址是否相等

4.2 判断被比较的对象类型是否是String

4.3 先比较长度是否相等,再一个一个的比较字符数组的值

5.hashCode方法

    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

5.1 如果字符串长度是0或当前hash值不为0,直接返回当前hash值。

5.2 算法为:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

6.substring方法

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

6.1 索引小于0或大于字符串长度,都会抛出越界异常

6.2 直接使用某个构造函数新建一个字符串对象

7.split方法

使用ArrayList存储分开的字符串

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值