Java字符串常量池示例詳解
為什么會有常量池的概念?
不知道小伙伴們是否有思考過這個問題? 沒有思考也無所謂,小編在這里類比一下,大家就會清晰了。什么是池? 我們聽的最多的池,應該是數(shù)據(jù)庫連接池. 為什么會有數(shù)據(jù)庫連接池,其實就是為了節(jié)省資源,提高性能,防止重復創(chuàng)建連接,避免占用內(nèi)存和網(wǎng)絡(luò)資源。
常量池其實就是跟數(shù)據(jù)庫連接池的目的都是一樣的。那么他是如何實現(xiàn)的呢? 因為常量池是JVM的概念,源碼我們也不好看,所以我們還以連接池來類比。
池化的目標就是緩存和管理
稍微提一點池化的概念,其實就是對資源做一個包裝,在包裝層來加一些對這個資源的屬性信息,比如使用次數(shù),最后操作時間,最長生命周期一樣。然后通過后臺線程對資源包裝層的掃描,來對真實資源的做一個管理。Google的Guava的Cache就是這么做的,我們自己也可以利用 common-pool2 工具包自己來做,或者說池化。
Java字符串常量池
在 JDK 1.7 之前,HotSpot 虛擬機中的字符串常量池都在方法區(qū)中,用永生代實現(xiàn)。JDK 1.7 及以后的版本,字符串常量池移到了堆里。
JDK 1.6 的 String.intern 方法會將首次遇到的 String 對象復制到永久代,并返回這個對象的引用。
JDK 1.7 的 String.intern 方法不再復制,而是記錄首次出現(xiàn)的 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
常量池可以看作是一個集合,沒有重復的元素。用雙引號創(chuàng)建的對象直接放到常量池,new 一定會在堆中創(chuàng)建一個新的對象,如果常量池沒有值相同的對象那么會在常量池也創(chuàng)建一個對象。intern 的作用是判斷常量池是否包含值相同的字符串,是則返回這個字符串對象的引用,否則將當前實例的引用放到常量池并返回當前實例的引用。
另外,字符串的拼接實際上是用了 StringBuilder,所以字符串 s8 的創(chuàng)建會伴隨以下對象的創(chuàng)建:
- 堆中兩個不同的 String 對象 1
- 字符串常量池中一個 String 對象 1
- 一個 StringBuilder 對象
- 堆中的 String 對象 11
由于 s8 的創(chuàng)建方式不是 new String 而是拼接,所以不會在常量池中創(chuàng)建值為“11”的對象,這也是 test5 和 test6 要對比的問題。
總結(jié)
到此這篇關(guān)于Java字符串常量池的文章就介紹到這了,更多相關(guān)Java字符串常量池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringMVC通過RESTful結(jié)構(gòu)實現(xiàn)頁面數(shù)據(jù)交互
RESTFUL是一種網(wǎng)絡(luò)應用程序的設(shè)計風格和開發(fā)方式,基于HTTP,可以使用XML格式定義或JSON格式定義。RESTFUL適用于移動互聯(lián)網(wǎng)廠商作為業(yè)務接口的場景,實現(xiàn)第三方OTT調(diào)用移動網(wǎng)絡(luò)資源的功能,動作類型為新增、變更、刪除所調(diào)用資源2022-08-08
Eclipse 出現(xiàn)Failed to load JavaHL Library解決方法
這篇文章主要介紹了Eclipse 出現(xiàn)Failed to load JavaHL Library解決方法的相關(guān)資料,今天使用Eclipse 時出現(xiàn)以上錯誤,本文說明如何更更正,需要的朋友可以參考下2016-11-11
詳解配置spring-boot-actuator時候遇到的一些小問題
這篇文章主要介紹了詳解配置spring-boot-actuator時候遇到的一些小問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11
Spring Boot中的SpringSecurity基礎(chǔ)教程
Spring Security是一個功能強大且高度可定制的身份驗證和訪問控制框架。它實際上是保護基于spring的應用程序的標準Spring Security是一個框架,側(cè)重于為Java應用程序提供身份驗證和授權(quán),這篇文章主要介紹了Spring Boot中的SpringSecurity學習,需要的朋友可以參考下2023-01-01

