String類和常量池

2021-09-10 23:06:49 字數 1581 閱讀 8807

1. 全域性字串常量池(string pool)

全域性字串常量池中存放的內容是在類載入完成後存到string pool中的,在每個vm中只有乙份,存放的是字串常量的引用值(在堆中生成字串物件例項)。

2. class檔案常量池(class constant pool)

class常量池是在編譯的時候每個class都有的,在編譯階段,存放的是常量(文字字串、final常量等)和符號引用。

3. 執行時常量池(runtime constant pool)

執行時常量池是在類載入完成之後,將每個class常量池中的符號引用值轉存到執行時常量池中,也就是說,每個class都有乙個執行時常量池,類在解析之後,將符號引用替換成直接引用,與全域性常量池中的引用值保持一致。

常量池

string str1 = "abc";

string str2 = new string("def");

string str3 = "abc";

string str4 = str2.intern();

string str5 = "def";

system.out.println(str1 == str3);// true

system.out.println(str2 == str4);// false

system.out.println(str4 == str5);// true

回到示例的那個程式,現在就很容易解釋整個程式的記憶體分配過程了,首先,在堆中會有乙個「abc」例項,全域性string pool中存放著「abc」的乙個引用值,然後在執行第二句的時候會生成兩個例項,乙個是「def」的例項物件,並且string pool中儲存乙個「def」的引用值,還有乙個是new出來的乙個「def」的例項物件,與上面那個是不同的例項,當在解析str3的時候查詢string pool,裡面有「abc」的全域性駐留字串引用,所以str3的引用位址與之前的那個已存在的相同,str4是在執行的時候呼叫intern()函式,返回string pool中「def」的引用值,如果沒有就將str2的引用值新增進去,在這裡,string pool中已經有了「def」的引用值了,所以返回上面在new str2的時候新增到string pool中的 「def」引用值,最後str5在解析的時候就也是指向存在於string pool中的「def」的引用值,那麼這樣一分析之後,結果就容易理解了。    的首先經過編譯之後,在該類的class常量池中存放一些符號引用,然後類載入之後,將class常量池中存放的符號引用轉存到執行時常量池中,然後經過驗證,準備階段之後,在堆中生成駐留字串的例項物件(也就是上例中str1所指向的「abc」例項物件),然後將這個物件的引用存到全域性string pool中,也就是string pool中,最後在解析階段,要把執行時常量池中的符號引用替換成直接引用,那麼就直接查詢string pool,保證string pool裡的引用值與執行時常量池中的引用值一致,大概整個過程就是這樣了。

也就是說當你用new為乙個string物件賦值時,會產生兩個不同的例項。當你呼叫intern函式時呼叫的是string pool中的例項,而非物件例項。

String類和常量池

string物件的兩種建立方式 string str1 abcd 先檢查字串常量池中有沒有 abcd 如果字串常量池中沒有,則建立乙個,然後 str1 指向字串常量池中的物件,如果有,則直接將 str1 指向 abcd string str2 new string abcd 堆中建立乙個新的物件 s...

String 類和常量池

1 string 物件的兩種建立方式 string str1 abcd 先檢查字串常量池中有沒有 abcd 如果字串常量池中沒有,則建立乙個,然後 str1 指向字串常量池中的物件,如果有,則直接將 str1 指向 abcd string str2 new string abcd 堆中建立乙個新的物...

String類和常量池

1 string物件建立物件的兩種方法 string str1 health 常量池中建立 strinng str2 new string health 堆中建立 system.out.println str1 str2 false2 string型別的常量池比較特殊 string a aaa 在常...