JSK1.8 String類部分原始碼分析
阿新 • • 發佈:2018-12-12
本文基於JDK1.8中的String類,看原始碼時無意發現String類中幾個比較有意思的地方,特此記錄下。
String類的兩個重要屬性,final的字元陣列和int的hash值,還有序列化相關的兩個欄位,這裡不寫;
final char value[]初始化後將是不可以變的,與String類的final關鍵字相呼應,保證的字串的不變性;特別是在初始化字串物件時,如果常量池中存在該字串,可以將value直接指向常量池中的字串,這樣既節省記憶體又方便,同時由於是final型別,也沒有多執行緒併發問題。
private int hash在JVM中,int型別預設初始化為0,在未調hashCode時hashCode一直是0,只有在調一次時還會生成。
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
hashCode()方法:
// hashCode生成規則,s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { // 只有第一次呼叫時才會生成一個hashCode並賦值 char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
compareTo()方法, 這個方法有意思的地方在while迴圈中,return c1 - c2,這種寫法,直接通過字元的ASCII碼相減得到一個int值,進行返回,高下立判斷:
public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; 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; }
構造方法String(String original),通過String構造自身的構造方法,省事,不需要通過Arrays.copyOf重新做一份copy,直接應用之前String類的value和賦值hash值,反正是final的:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
intern()方法,這是個本地方法,通過此方法可以將字串陣列放到方法區(不同JDK版本方法區叫法位置可能不一樣,這也是需要研究的),合適的時候呼叫intern方法,可以減少建立物件的個數,減少記憶體開銷(共用了記憶體啊)。
public native String intern();