天天看点

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存储分开的字符串

继续阅读