您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Java字符串常量池的作用是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
不知道小伙伴們是否有思考過這個問題? 沒有思考也無所謂,小編在這里類比一下,大家就會清晰了。什么是池? 我們聽的最多的池,應該是數據庫連接池. 為什么會有數據庫連接池,其實就是為了節省資源,提高性能,防止重復創建連接,避免占用內存和網絡資源。
常量池其實就是跟數據庫連接池的目的都是一樣的。那么他是如何實現的呢? 因為常量池是JVM的概念,源碼我們也不好看,所以我們還以連接池來類比。
稍微提一點池化的概念,其實就是對資源做一個包裝,在包裝層來加一些對這個資源的屬性信息,比如使用次數,最后操作時間,最長生命周期一樣。然后通過后臺線程對資源包裝層的掃描,來對真實資源的做一個管理。Google的Guava的Cache就是這么做的,我們自己也可以利用 common-pool2 工具包自己來做,或者說池化。
在 JDK 1.7 之前,HotSpot 虛擬機中的字符串常量池都在方法區中,用永生代實現。JDK 1.7 及以后的版本,字符串常量池移到了堆里。
JDK 1.6 的 String.intern 方法會將首次遇到的 String 對象復制到永久代,并返回這個對象的引用。
JDK 1.7 的 String.intern 方法不再復制,而是記錄首次出現的 String 對象的引用。
以下用 JDK 1.8 實驗探究字符串常量池。
// test1 String s1 = "red"; String s2 = "red"; System.out.println(s1 == s2); // true // test2 String s3 = new String("red"); String s4 = new String("red"); System.out.println(s3 == s4); // false // test3 System.out.println(s1 == s3); // false // test4 System.out.println(s3.intern() == s1); // true System.out.println(s3.intern() == s3); // false System.out.println(s3.intern() == s4); // false // test5 String s5 = new String("thunder"); String s6 = s5.intern(); String s7 = "thunder"; System.out.println(s5 == s6); // false System.out.println(s6 == s7); // true // test6 String s8 = new String("1") + new String("1"); // String s8 = new StringBuilder().append().toString() String s9 = s8.intern(); String s10 = "11"; System.out.println(s8 == s9); // true System.out.println(s9 == s10); // true
常量池可以看作是一個集合,沒有重復的元素。用雙引號創建的對象直接放到常量池,new 一定會在堆中創建一個新的對象,如果常量池沒有值相同的對象那么會在常量池也創建一個對象。intern 的作用是判斷常量池是否包含值相同的字符串,是則返回這個字符串對象的引用,否則將當前實例的引用放到常量池并返回當前實例的引用。
另外,字符串的拼接實際上是用了 StringBuilder,所以字符串 s8 的創建會伴隨以下對象的創建:
堆中兩個不同的 String 對象 1
字符串常量池中一個 String 對象 1
一個 StringBuilder 對象
堆中的 String 對象 11
由于 s8 的創建方式不是 new String 而是拼接,所以不會在常量池中創建值為“11”的對象,這也是 test5 和 test6 要對比的問題。
關于Java字符串常量池的作用是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。