【源碼分析】----String

本文分析的爲JDK7中的String類

String類:
這裏寫圖片描述
這裏可以看出String被final修飾,是個不可變量,線程安全的,並且不允許被繼承。
並且實現了Serializable(可以進行序列化和反序列化),Comparable(可以進行自定義的字符串比較),CharSequence(一個可讀序列)接口。

String屬性:
這裏寫圖片描述

這裏包含兩個屬性,一個不可變的char數組,說明String本身就是一個字符數組。
另一個是String的hash值,默認爲0。

String方法:
這裏挑選一些比較常用和重要的方法進行解釋

首先是構造方法:去掉了將刪除的方法,後面的方法沒有解釋,相信大家基本都能看懂

//默認構造方法,一般不用,因爲String字符串是不可改變的
public String() {
    this.value = new char[0];
}
//使用已存在的一個字符串創建一個相同字符序列的字符串
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}
//使用一個字符數組創建一個字符串
public String(char value[]) {
    //複製字符數組並賦值給value
    this.value = Arrays.copyOf(value, value.length);
}
//使用字符數組的一部分創建一個字符串對象 offset爲字符數組開始位置,count爲數組開始位置往後的長度
public String(char value[], int offset, int count) {
    if (offset < 0) {
        throw new StringIndexOutOfBoundsException(offset);
    }
    if (count < 0) {
        throw new StringIndexOutOfBoundsException(count);
    }
    if (offset > value.length - count) {
        throw new StringIndexOutOfBoundsException(offset + count);
    }
    this.value = Arrays.copyOfRange(value, offset, offset+count);
}
//將int數組轉換成String,offset爲數組開始位置,count爲數組開始位置往後的長度
public String(int[] codePoints, int offset, int count) {
    if (offset < 0) {
        throw new StringIndexOutOfBoundsException(offset);
    }
    if (count < 0) {
        throw new StringIndexOutOfBoundsException(count);
    }
    // Note: offset or count might be near -1>>>1.
    if (offset > codePoints.length - count) {
        throw new StringIndexOutOfBoundsException(offset + count);
    }

    final int end = offset + count;

    // Pass 1: Compute precise size of char[]
    int n = count;
    for (int i = offset; i < end; i++) {
        int c = codePoints[i];
        if (Character.isBmpCodePoint(c))
            continue;
        else if (Character.isValidCodePoint(c))
            n++;
        else throw new IllegalArgumentException(Integer.toString(c));
    }

    // Pass 2: Allocate and fill in char[]
    final char[] v = new char[n];

    for (int i = offset, j = 0; i < end; i++, j++) {
        int c = codePoints[i];
        if (Character.isBmpCodePoint(c))
            v[j] = (char)c;
        else
            Character.toSurrogates(c, v, j++);
    }

    this.value = v;
}
//將字節數組轉成String,charsetName爲編碼格式
public String(byte bytes[], int offset, int length, String charsetName)
            throws UnsupportedEncodingException {
    if (charsetName == null)
        throw new NullPointerException("charsetName");
    checkBounds(bytes, offset, length);
    this.value = StringCoding.decode(charsetName, bytes, offset, length);
}

public String(byte bytes[], int offset, int length, Charset charset) {
    if (charset == null)
        throw new NullPointerException("charset");
    checkBounds(bytes, offset, length);
    this.value =  StringCoding.decode(charset, bytes, offset, length);
}

public String(byte bytes[], String charsetName)
        throws UnsupportedEncodingException {
    this(bytes, 0, bytes.length, charsetName);
}

public String(byte bytes[], Charset charset) {
    this(bytes, 0, bytes.length, charset);
}

public String(byte bytes[], int offset, int length) {
    checkBounds(bytes, offset, length);
    this.value = StringCoding.decode(bytes, offset, length);
}

public String(byte bytes[]) {
    this(bytes, 0, bytes.length);
}

public String(StringBuffer buffer) {
    synchronized(buffer) {
        this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
    }
}

public String(StringBuilder builder) {
    this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

常用方法:

//返回字符串長度
public int length() {
   return value.length;
}
//判斷字符串是否爲空
public boolean isEmpty() {
    return value.length == 0;
}
//根據下標獲取字符
public char charAt(int index) {
   if ((index < 0) || (index >= value.length)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index];
}

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值乘31+該字符
        }
        hash = h;
    }
    return h;
}
//判斷值是否相等
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;
}
//本地方法
public native String intern();

後面的慢慢補充

intern方法特別解釋一下: String的intern()方法的原理,在調用此方法時候會初始化一個空的字符串池,然後將該字符串對象加入該池中,當再次調用這個方法的時候,會判斷這個池中是否包含字符串,如果包含則從池中返回這個字符串,否則加入這個字符串並返回這個字符串對象的引用,如果在線程中用String鎖,可能需要用到這個方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章