String類源碼閱讀記錄

在開發過程當中String是一個高頻使用的類,可是一直沒有仔細去閱讀過源碼。打開源碼得知String是一個final的類,它實現了Serializable、Comparable和CharSequence接口java

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0
    //省略...
}

String類包含三個屬性:數組

/** 存儲字符串中的字符*/
    private final char value[];

    /** 緩存string的hashcode值 */
    private int hash; // Default to 0
    /**
     * 序列持久化
     */
    private static final ObjectStreamField[] serialPersistentFields =
            new ObjectStreamField[0];

String的底層使用char數組實現的。String重寫了Object的equals和hashcode的方法。緩存

String的equals方法實現以下:jvm

/**
 * 比較當前字符串和指定的對象,只有當指定對象不爲null而且對象中的字符序列相同時
 * 才返回true
 */
public boolean equals(Object anObject) {
    //兩個對象的引用地址相同返回true
    if (this == anObject) {
        return true;
    }
    //只有String類型的數據纔有效
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        //若是包含的字符長度不相等返回false
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            //從後往前判斷單個字符,同等序號若是不相等則返回false
            while (n-- != 0) {
                if (v1[i] != v2[i])
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

String的hashCode實現以下:測試

String是使用value值來做爲hash運算,那麼若是String的value相等那麼它們的hashCode值一定相等,那麼用String的equals比較也是相等的,同時也能夠看出對於String若是它的equals相等,那麼它的hashCode值優化

也必定相等,固然hashCode值相等不能表明兩個String相等。this

在String的Hash計算中使用一個計算常數31,31是通過測試均勻分佈的獲得的結果,並且31能夠被jvm優化採用移位運算31 = (i<<5)-1code

/**
     * 返回字符串的hash值
     * 計算公式:
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * s[i]是指String中的字符,n是指String的長度
     */
    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;
    }

String intern方法介紹:intern方法是一個native的方法,當intern方法被調用,它會使用equals方法去字符串常量池中比較查找,若是找到則返回,若是沒有找到的將新的字符串添加到字符串常量池中,而後返回對象的引用。對於任何的兩個String對象s和t,當前僅當s.equals(t)爲true時,s.intern()==t.intern()才爲true對象

public native String intern();

 

String的內存操做:接口

在jvm內存分配中有兩個重要的部分,一個是heap一個是stack,棧用於存儲對象的引用,

heap用戶存儲具體的對象。在jdk1.7後(字符串常量池被移到了heap中)jvm分配 一些內存專門用於存儲string的字面量,這是堆內存的一部分,它被稱做字符串常量池(String Constant Pool),例如 :String a = "abc"; 若是使用了new操做來建立字符串則對象會被存儲到堆內存中

注意:當你使用一個字面量來建立一個String對象時,jvm會首先在字符串常量池中檢查是否已經存在,若是找到則返回對象的引用,若是沒有的建立一個新的對象

相關文章
相關標籤/搜索