專題整理之—String的字符串常量池

為了加深對Java語言的理解,加深對Java各種特性的理解與掌握,平常會自己歸納一些專題的分析和總結(jié)。基于自己的理解,感覺哪些部分適合在一起進(jìn)行總結(jié),就歸納為一個專題了??赡芤粋€專題里面的東西也不屬于一個類別,或者也比較雜亂,請見諒。
本文是在總結(jié)不可變對象與String的不可變中,涉及到的String的字符串常量池。感覺這個部分比較重要,面試也經(jīng)??嫉竭@些,就單獨(dú)拿出來作為一個專題。(此篇總結(jié)大部分是借鑒了CSDN的一篇文章,然后加上了一些自己的理解)

字符串常量池:

  • 為了減少在jvm中創(chuàng)建的字符串的數(shù)量,字符串類維護(hù)了一個字符串常量池,字符串常量池(String pool)是Java堆內(nèi)存中一個特殊的存儲區(qū)域;
  • 當(dāng)創(chuàng)建String對象時,jvm會先檢查字符串常量池,如果這個字符串的常量值已經(jīng)存在在池中了,就直接返回池中對象的引用,如果不在池中,就會實(shí)例化一個字符串并放入池中;
  • 常量池:用于保存java在編譯期就已經(jīng)確定的,已經(jīng)編譯的class文件中的一份數(shù)據(jù)。包括了類、方法、接口中的常量,也包括字符串常量,如String s = "a"這種聲明方式;
String s1 = "aaa";
String s2 = "aaa";
1PAI~[D5DA))%XZ~5S6])RH.png

從日常的面試題展開:

String s = new String("abc"); //創(chuàng)建了幾個對象

兩個;
第一個對象是"abc"字符串存儲在常量池中;
第二個對象是創(chuàng)建在Heap中的String對象;這里的s是放在棧里面的指向了Heap堆中的String對象。

String s1 = new String("s1") ;
String s2 = new String("s1") ; //創(chuàng)建了幾個對象

三個;
第一個是編譯期就已經(jīng)創(chuàng)建在常量池中創(chuàng)建的"s1",因?yàn)閯?chuàng)建一個之后常量池中就會有,不再創(chuàng)建,直接指向;
后面兩個是運(yùn)行期使用new創(chuàng)建在堆上的s1和s2;

示例1:

String s0 = "111";              //pool
String s1 = new String("111");  //heap
final String s2 = "111";        //pool
String s3 = "sss111";           //pool
String s4 = "sss" + "111";      //pool
String s5 = "sss" + s0;         //heap 
String s6 = "sss" + s1;         //heap
String s7 = "sss" + s2;         //pool
String s8 = "sss" + s0;         //heap
 
System.out.println(s3 == s4);   //true
System.out.println(s3 == s5);   //false
System.out.println(s3 == s6);   //false
System.out.println(s3 == s7);   //true
System.out.println(s5 == s6);   //false
System.out.println(s5 == s8);   //false

示例2:

String str1 = "abc";
String str2 = "abc";
String str3 = "abc";
String str4 = new String("abc");
String str5 = new String("abc");
String str6 = new String("abc");
@DPKA4RS@H{0GJJ7SH)FPP8.png

結(jié)論:

  1. 單獨(dú)使用""引號創(chuàng)建的字符串都是常量,編譯器就已經(jīng)存儲到常量池中了;
  2. 使用new String()創(chuàng)建的是對象會存儲到heap中,是運(yùn)行期創(chuàng)建的;
  3. 使用只包含常量的字符串連接符如"a"+"a"創(chuàng)建的也是常量,編譯器就能確定,并存儲到常量池"aa",但不會有"a"存在;
  4. 使用包含變量的字符串連接符如"a"+s1創(chuàng)建的對象會存儲在堆中,運(yùn)行時期才創(chuàng)建;只要s1是變量,不論s1指向池常量池中的字符串對象還是堆中的字符串對象,運(yùn)行期"a"+s1操作實(shí)際上是編譯器創(chuàng)建了StringBuilder對象進(jìn)行了append操作后通過toString()返回了一個字符串對象存在heap上。
  5. 對于final String s2 = "111",是一個用final修飾的變量,在編譯期就已知了,在包含變量的字符串連接符"a"+s2時直接用常量"111"來代替s2,等效于"a"+"111",在編譯期就已經(jīng)生產(chǎn)了字符串對象"a111"對象在常量池中。

目前全部文章列表:
idea整合restful風(fēng)格的ssm框架(一)
idea整合restful風(fēng)格的ssm框架(二)
idea整合spring boot+spring mvc+mybatis框架
idea整合springboot+redis
JVM學(xué)習(xí)之—Java內(nèi)存區(qū)域
JVM學(xué)習(xí)之—垃圾回收與內(nèi)存分配策略
專題整理之—不可變對象與String的不可變
專題整理之—String的字符串常量池

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 從網(wǎng)上復(fù)制的,看別人的比較全面,自己搬過來,方便以后查找。原鏈接:https://www.cnblogs.com/...
    lxtyp閱讀 1,436評論 0 9
  • ??需要說明的一點(diǎn)是,這篇文章是以《深入理解Java虛擬機(jī)》第二版這本書為基礎(chǔ)的,這里假設(shè)大家已經(jīng)了解了JVM的運(yùn)...
    Geeks_Liu閱讀 14,281評論 5 44
  • 前言 RTFSC (Read the fucking source code )才是生活中最重要的。我們天天就是要...
    二毛_coder閱讀 524評論 1 1
  • 前面有幾篇文章分析了我對合格CTO的定義,以及普通技術(shù)人員如何快速成長為合格CTO,有不少朋友跟我反饋,非常同意我...
    杜仲閑談閱讀 917評論 0 3
  • 今天開家長會,因?yàn)槲疑习啵龐寢屌R時出差,沒有去,炎瑋有點(diǎn)小失落。炎瑋說今天的節(jié)目她喜歡前面四個武術(shù)節(jié)目,還有后面...
    李炎瑋爸爸閱讀 243評論 0 0

友情鏈接更多精彩內(nèi)容