Constant Pool
常量池的優勢
為了避免頻繁的創建和銷毀對象而影響系統性能,其實現了對象的共享。
解析流程
與 ClassLoader 機制息息相關
ClassLoader 機制ClossLoading 編譯時期 (Class Constant Pool)
ClossLoading 加載完成 (將 Class Constant Pool 的內容存放到 Runtime Constant Pool 中)
Linking / 準備 (String literal Pool 生成參考值)
Linking / 解析 (運行時常量池中的符號參考替換成直接參考)
Class Constant Pool
每個類別 ClossLoading 時期產生,.class 文件中除了包含類別的版本、屬性、方法、介面等描述信息放在方法區外,另外就是常量池 (constant pool table),用於存放生成的兩大類型常量:
⭐ 字面量 (Literal)
字串
被聲明為 final 的常量參數值
⭐ 符號參考 (Symbolic References)
類別和介面的全名 - 如:Object,Ljava/lang/Object;
屬性的名稱和權限符號
方法的名稱和權限符號
名稱參考 .class 結構
N .class 結構Runtime Constant Pool
ClassLoader 加載完成後,就會將 .class常量池中的內容存放到運行時常量池中,
❗ 由此可知,運行時常量池內也是每個類別都會有一份內容。
Runtime Constant Pool 相對於 Class Constant Pool 的另一個重要特徵是具備動態性。
運行時常量池裡的內容是能夠動態添加的。
Java語言並不要求常量一定只有編譯時期才能產生,
也就是並非預置入 .class文件中常量池的內容才能進入方法區運行時常量池,
運行期間也可能將新常量放入池中,如: String類別的 intern() 方法。
String literal Pool
又稱 String pool,是在 .class classLoading 完成,並經過驗證,到了"準備" 階段之後,
在 Heap 中生成字串的對象,然後將該字串對象的參考值存到 string pool 中,
具體的實例對象是存放在 Heap 中的一塊空間,屬於 Global Pool。
優點
節省內存空間
常量池中所有相同的字符串常量被合併,只佔用一個空間。
節省運行時間
比較字符串時,== 比 equals() 快。 對於兩個引用變量,只用 == 判斷是否相等,也就可以判斷實際值是否相等。
String 類別的 intern() 方法
是一個 Native 方法。
會查找 String pool 中是否存在一份 equal 相等的字符串,如果有則返回該字符串的參考,
如果沒有則添加新的字符串進入池中。
參考資料
http://tangxman.github.io/2015/07/27/the-difference-of-java-string-pool/ https://www.jianshu.com/p/c7f47de2ee80 https://blog.csdn.net/qq_26222859/article/details/73135660
Last updated
Was this helpful?