對(duì)于常量池而言,字符串的概念較為廣泛,并不單指字符串變量。類名、方法名、類型、this指針名,等等,都可以看作是字符串,最終都會(huì)被JVM當(dāng)作字符串處理、存儲(chǔ)到符號(hào)區(qū)。
由于無論是tag還是constantPool的數(shù)據(jù)區(qū),一個(gè)存儲(chǔ)位置只能存放一個(gè)指針寬度的數(shù)據(jù),而字符串往往很大,因此JVM專門設(shè)計(jì)一個(gè)“符合表”的內(nèi)存區(qū),tag和constantPool數(shù)據(jù)區(qū)內(nèi)僅保存指針指向符號(hào)區(qū)。
JVM對(duì)字符串的處理如下:

以上代碼給出了一個(gè)基本思路,即字節(jié)碼文件中的字符串常量池元素最終都會(huì)被保存到符號(hào)表中,為了節(jié)省內(nèi)存,JVM會(huì)先判斷符號(hào)表中是否存在相同的字符串,如果已經(jīng)存在,則不會(huì)申請(qǐng)內(nèi)存。這就是如果你在一個(gè)類中定義了兩個(gè)字符串,但是這兩個(gè)字符串的值相同,最終這兩個(gè)字符串變量都會(huì)同時(shí)指向常量池中同一個(gè)位置的原因。