String原始碼分析

2022-05-02 11:21:07 字數 2837 閱讀 8227

前言:string類在日常開發過程中使用頻率非常高,平時大家可能看過string的原始碼,但是真的認真了解過它麼,筆者在一次筆試過程中要求寫出string的equals方法,瞬間有點懵逼,憑著大致的理解,算是寫出來了,可是下來一翻string的原始碼頓悟,原來自己寫得是多麼的low,所以有必要把這些基礎知識點記錄下來,加深印象。

注:本文jdk原始碼版本為jdk1.8.0_172

首先string是不可變物件,其體現主要在string類是被final關鍵字修飾,因此該物件不能被繼承,不能被修改。那你可能要問了為什麼我們在日常操作過程中不是可以很方便的修改string的內容嗎?其實我們修改其內容是new了乙個物件,原來的內容並沒有改變。

string內部是通過char陣列來儲存的內容,從以下原始碼中可以發現:

注:這裡的char陣列也是被final修飾。

不知道你注意沒,string的建構函式非常的多:

這裡挑選幾個筆者認為有特點的建構函式進行分析,其它建構函式請檢視相應原始碼。

#1.預設建構函式:

1

public string()

注:預設建構函式的實現非常簡單,就是返回空字串的陣列形式。

#2.入參為char陣列:

1

public string(char value)

分析:如果傳入char陣列,是通過arrays#copyof方法進行拷貝的。

#3.入參為string物件:

1

public string(string original)

分析:如果入參為string物件,則直接進行相應的賦值即可(value和hash值)。

#4.入參為stringbuffer:

1

public string(stringbuffer buffer)

5 }

分析:這裡對stringbuffer進行了加鎖,然後再進行拷貝操作。為什麼要對stringbuffer加鎖呢?stringbuffer不是執行緒安全的嗎?其實這裡對其進行加鎖正是為了保證在多執行緒環境下只能有乙個執行緒去操作stringbuffer物件,這裡需要注意一下。

#5.入參為stringbuilder:

1

public string(stringbuilder builder)

分析:對比stringbuffer入參,如果用stringbuilder作為入參是不加鎖操作的,因為stringbuilder本身執行緒不安全,但會提公升效能,並且其原始碼上也做出了相應注釋。

注意:以stringbuffer和stringbuilder為入參的建構函式這裡要特別關注一下:stringbuffer執行緒安全,為了保證在string中也執行緒安全所以需要加鎖,而stringbuilder非執行緒安全,因此不需要加鎖操作,直接進行拷貝即可。

1

public

inthashcode()

9 hash =h;10}

11return

h;12 }

分析:string的hashcode方法還是比較簡單的,它是遍歷char陣列以31為基數做乙個累加操作。注意這裡是以31來作為的基數,為什麼取31作為基數可參考:string hashcode 方法為什麼選擇數字31作為乘子

1

public

boolean

equals(object anobject)

5if (anobject instanceof

string)

17return

true;18

}19}20

return

false

;21 }

分析:首先會判斷是否是同乙個物件,如果是,則直接返回true;其次判斷傳入物件是否為string物件,如果物件不匹配直接返回false,否則依次比較兩個物件的char,只要發現乙個不相等,則直接返回false,停止迴圈。這裡的寫法還是比較簡潔的,在日常開發中可以利用起來。

關於不可變物件,這裡看一段原始碼就清楚了

1

public string substring(int

beginindex)

5int sublen = value.length -beginindex;

6if (sublen < 0)

9return (beginindex == 0) ? this : new

string(value, beginindex, sublen);

10 }

擷取函式,直接看第9行**處,如果beginindex==0,返回的是當前物件,否則這裡是new的乙個新物件,其實string中的很多函式都是這樣的操作,具體可翻看原始碼閱讀一下。

#2.string類的建構函式非常多,需要注意一下,特別是stringbuffer和stringbuilder為入參的建構函式。

#3.string是不可變物件

#4.string#hashcode的計算方式,以31為計算基數。

by shawn chen,2019.08.20日,上午。

原始碼分析之String

先看屬性 底層是char陣列,一目了然 可以看到,value是儲存string的內容的,即當使用string str abc 的時候,本質上,abc 是儲存在乙個char型別的陣列中的。string底層的儲存結構是乙個字元型別的陣列,同樣也是被final修飾,因此一旦這個字元陣列被建立後,value...

STL原始碼分析 string

從定義可知,string其實是base string的特化類,string使用預設的記憶體分配器 stl default allocator chart template class alloc stl default allocator chart class basic string typed...

關於String原始碼分析

關於string的類定義 public final class string implements j a.io.serializable,comparable,charsequence 以final修飾,不可繼承,不可變,其方法預設都是final的 實現 serializable comparab...