快速理解Java字符串常量池

快速理解Java字符串常量池


本篇課程不來虛的,上來就是幹活,現在發車。小編通過代碼案例及比喻,帶你一窺究竟。

爲什麼會有常量池的概念?

不知道小夥伴們是否有思考過這個問題? 沒有思考也無所謂,小編在這裏類比一下,大家就會清晰了。
什麼是池? 我們聽的最多的池,應該是數據庫連接池. 爲什麼會有數據庫連接池,其實就是爲了節省資源,提高性能,防止重複創建連接,避免佔用內存和網絡資源。

常量池其實就是跟數據庫連接池的目的都是一樣的。那麼他是如何實現的呢? 因爲常量池是JVM的概念,源碼我們也不好看,所以我們還以連接池來類比,請看下文。

池化的目標就是緩存和管理

稍微提一點池化的概念,其實就是對資源做一個包裝,在包裝層來加一些對這個資源的屬性信息,比如使用次數,最後操作時間,最長生命週期一樣。然後通過後臺線程對資源包裝層的掃描,來對真實資源的做一個管理。Google的Guava的Cache就是這麼做的,我們自己也可以利用 common-pool2 工具包自己來做,或者說池化。

JVM常量池就相當於一個緩存

常量就是不會改變的信息,那麼既然是不會改變的信息,系統中只存在一份,就可以了。存在多份也是浪費內存資源。然而在Java中只要是new的信息都會在堆上開闢一個新的空間,爲了解決這個問題,JVM中才出現了字符串常量池的概念。但是隻有直接用""修飾的字符,纔會被加入到常量池中,當再次用""創建的時候,會首先從常量池中去獲取。

String s1 = "1";
String s2 = "1";
//true
System.out.print(s1==s2); 
String s3 = new String("1");
String s4 = new String("1");
//false
System.out.print(s3==s4); 

我們可以把常量池理解爲一個Map<String,String>做的緩存容器。只不過這個緩存機制是有JVM使用C語言寫的。我們看不到而已。

String.intern()的使用

new 出來的 String 類型是否也能使用常量池呢? 當然可以,就是通過 intern 方法
這個方法的意思就是先到緩存中(也就是常量池中)查詢當前對象是否存在,存在就返回常量池中地址,不存在就加入常量池。我們可以用一段僞代碼來解釋一波。

        //雙引號直接放入常量池
        String s1 = "1";
        String s2 = new String("1");
        //false
        System.out.println(s1 == s2);
        //先到常量池中查詢是否有”1“,存在就將常量池中對象返回,不存在就放到常量池中(此時常量池中存在s1)
        //於是就將s1的值重新複製給s3,所以s1 == s3
        String s3 = new String("1").intern();
        //true
        System.out.println(s1 == s3);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章