java String 源碼解析

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

    // 內部結構存儲是char數據,用於存儲字符串的值
    private final char value[];

    // 緩存字符串的 hash code 
    private int hash; // Default to 0

   
    private static final long serialVersionUID = -6849794470754667710L;

     // 以String 爲參數的構造方法
     public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
     }
    // 以char[]數組爲參數的構造方法 
     public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }
    // 以StringBuffer爲參數的構造方法
    public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }
    // 以StringBuilder爲參數的構造方法
    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }
   
    /**
     * String 類型重寫了Object 中的equals()方法,equals()方法需要傳遞一個Object類型的參數
     * 值,在比較時會先通過instanceof 判斷是否String類型,如果不是則會直接返回false
     */
    public boolean equals(Object anObject) {
        // 對象引用地址相同直接返回 true
        if (this == anObject) {
            return true;
        }
        // 判斷入參 anObject 類型是否爲String類型,若不是 則返回 false
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                // 把兩個字符串轉換成char[]數組進行對比
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                // 循環比較兩個字符串的每一個字符串
                while (n-- != 0) {
                    // 若其中有一個字符串不相等返回false,否則繼續比較
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                // 當所有字符都相等的時候返回true 
                return true;
            }
        }
        return false;
    }
    /**
     *比較兩個字符串
     * 若兩個字符串分別存儲1 和 2,返回的值爲 -1
     * 若兩個字符串分別存儲1 和 1,返回的值爲 0
     * 若兩個字符串分別存儲2 和 1,返回的值爲 1
     */
    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        // 獲取兩個字符串長度最短的那個 int的值
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        // 對比每一個字符
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                // 字符不相等就直接返回差值
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

}

從源碼 可以看出 ,compareTo() 方法 和 equals() 方法都是用於比較連個字符串的,但他們有兩點不同:

1.equals() 可以接收一個Object類型的參數,而 compareTo() 只能接收一個String類型的參數

2.equals() 返回值爲boolean類型, 而compareTo()返回值則爲int類型

3. equals()方法返回true的時候表示兩個字符串相等,comparaTo() 返回0 的時候表示兩個字符串相等

拓展:

 1.  == 和equals() 的區別

== 對於基本數據類型來說,是用戶比較 "值" 是否相等

對於引用數據類型來說,是用戶比較引用地址是否相同的

通過查看 Object中的equals( ) 方法

public class Object {
     public boolean equals(Object obj) {
        return (this == obj);
     }
}

equals()方法其實底層就是使用==, 而String重寫了equals() 方法把它修改成比較兩個字符串的值是否相等

 

String 在JVM中的存儲:


        String str1 = new String("java");
        String str2 = str1.intern();
        String str3 = "java";
        System.out.println(str1 == str2); // false
        System.out.println(str2 == str3); // true

String常見的創建方式有兩種:

直接賦值的方式“Strings1="Java";”和“Strings2=newString("Java");”的方式,但兩者在JVM的存儲區域卻截然不同.

在JDK1.8中,變量str1會先去字符串常量池中找改字符串 "java",如果存在改字符串,則直接返回常量句柄,如果沒有此字符串,則會

現在常量池中創建此字符串,然後再返回常量句柄; 而變量str2是直接在堆上創建一個變量, 只有調用intern() 方法擦灰把此字符串保存到常量池中

 

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