首先,先看一下intern方法(JDK1.8)的官方檔案:

全是英文,閱讀起來有點困難怎么辦?沒關系,博主對此做了翻譯:
回傳字串物件的規范表示形式,
最初為空的字串池由類字串私人維護,
呼叫intern方法時,如果池中已包含一個字串,該字串等于由equals(object)方法確定的該字串物件,則回傳池中的字串,否則,將此字串物件添加到池中,并回傳對該字串物件的參考,
因此,對于任意兩個字串s和t,s.intern()==t.intern()當且僅當s.equals(t)為真時才為真,
所有文字字串和字串值常量運算式都是內部的,字串文字在Java的第3.10.5節中定義? 語言規范,
回傳值:
與此字串具有相同內容,但保證來自唯一字串池的字串,
還是看不懂怎么辦?以下博主將對intern方法進行全面講解:
要想具體了解String中的intern方法,首先你要了解一下JVM的記憶體結構,認識串池(StringTable),
以下是JDK1.6相關的記憶體結構:

以下是JDK1.8相關的記憶體結構:

隨著記憶體結構的改變String中的intern方法功能也發生了改變,
本片文章主要以JDK1.8為例,先看以下這段代碼:
public class Test{ String s1 = new String("a") + new String("b"); s1.intern();//① String s2 = "ab";//② System.out.println(s1 == s2); }
運行結果為true;
具體原因是:當String物件呼叫intern方法時,如果池中未包含相同的字串,將此字串物件添加到池中,并回傳對該字串物件的參考,
運行的主要流程為:
(1)String s1 = new String(“a”) + new String(“b”);
首先創建StringBuilder物件,用于字串拼接;
然后在堆中創建了String(“a”)物件,然后在字串常量池中放入字串"a",再做StringBuilder的append操作;
然后在堆中創建了String(“b”)物件,然后在字串常量池中放入字串"b",再做StringBuilder的append操作;
最后對StringBuilder做toString操作,注意此時只會在堆記憶體創建物件,并不會在串池中創建,
(2)s1.intern();
常量池中不直接放入"ab",而是參考堆中已經創建的String(“ab”),
(3)String s2 = “ab”;
s2指向字串常量池中的"ab",實際上是指向了堆中的String(“ab”),
但當我們調換①和②的位置時結果為falus,這是什么原因呢?
呼叫intern方法時,如果池中已包含一個字串,該字串等于由equals(object)方法確定的該字串物件,則回傳池中的字串,
所以,當調換①和②后,代碼將會首先在串池中創建一個“ab”,然后當執行s1.intern()時就會直接回傳串池中的"ab",但此時堆記憶體中的String("ab")物件和串池中的"ab"不為同一個,于是回傳falus,
但別忘了,JDK1.6和JDK1.8卻是不同的,
JDK1.6的作用是:檢查常量池里是否存在“ab”這么一個字串,如果存在,就回傳池里的字串,如果不存在,該方法會把“ab”添加到字串池中(此時這個"ab"并不是堆記憶體中的那個String(”ab“)而是一個新的"ab"),然后再回傳它的參考,所以如果是JDK1.6下以上兩張情況將都回傳falus,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/508076.html
標籤:其他
上一篇:女同桌找我要表情包,還好我會Python,分分鐘給她下載幾十個G...
下一篇:python基礎(待補充)
