精品专区-精品自拍9-精品自拍三级乱伦-精品自拍视频-精品自拍视频曝光-精品自拍小视频

網站建設資訊

NEWS

網站建設資訊

如何進行Java字符串池StringPool的深度解析

這篇文章給大家介紹如何進行Java字符串池String Pool的深度解析,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

為銀海等地區用戶提供了全套網頁設計制作服務,及銀海網站建設行業解決方案。主營業務為成都網站設計、成都網站制作、銀海網站設計,以傳統方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業、用心的態度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

      在工作中,String類是我們使用頻率非常高的一種對象類型。JVM為了提升性能和減少內存開銷,避免字符串的重復創建,其維護了一塊特殊的內存空間,這就是我們今天要討論的核心,即字符串池(String Pool)。字符串池由String類私有的維護。

      我們知道,在Java中有兩種創建字符串對象的方式:1)采用字面值的方式賦值  2)采用new關鍵字新建一個字符串對象。這兩種方式在性能和內存占用方面存在著差別。

      方式一:采用字面值的方式賦值,例如:

      如何進行Java字符串池String Pool的深度解析

      采用字面值的方式創建一個字符串時,JVM首先會去字符串池中查找是否存在"aaa"這個對象,如果不存在,則在字符串池中創建"aaa"這個對象,然后將池中"aaa"這個對象的引用地址返回給字符串常量str,這樣str會指向池中"aaa"這個字符串對象;如果存在,則不創建任何對象,直接將池中"aaa"這個對象的地址返回,賦給字符串常量。

      在本例中,執行:str == str2 ,會得到以下結果:

      如何進行Java字符串池String Pool的深度解析

      這是因為,創建字符串對象str2時,字符串池中已經存在"aaa"這個對象,直接把對象"aaa"的引用地址返回給str2,這樣str2指向了池中"aaa"這個對象,也就是說str和str2指向了同一個對象,因此語句System.out.println(str == str2)輸出:true。

     方式二:采用new關鍵字新建一個字符串對象,例如:

     如何進行Java字符串池String Pool的深度解析

     采用new關鍵字新建一個字符串對象時,JVM首先在字符串池中查找有沒有"aaa"這個字符串對象,如果有,則不在池中再去創建"aaa"這個對象了,直接在堆中創建一個"aaa"字符串對象,然后將堆中的這個"aaa"對象的地址返回賦給引用str3,這樣,str3就指向了堆中創建的這個"aaa"字符串對象;如果沒有,則首先在字符串池中創建一個"aaa"字符串對象,然后再在堆中創建一個"aaa"字符串對象,然后將堆中這個"aaa"字符串對象的地址返回賦給str3引用,這樣,str3指向了堆中創建的這個"aaa"字符串對象。

     在這個例子中,執行:str3 == str4,得到以下結果:

     如何進行Java字符串池String Pool的深度解析

     因為,采用new關鍵字創建對象時,每次new出來的都是一個新的對象,也即是說引用str3和str4指向的是兩個不同的對象,因此語句System.out.println(str3 == str4)輸出:false。

     字符串池的實現有一個前提條件:String對象是不可變的。因為這樣可以保證多個引用可以同事指向字符串池中的同一個對象。如果字符串是可變的,那么一個引用操作改變了對象的值,對其他引用會有影響,這樣顯然是不合理的。

     字符串池的優缺點:字符串池的優點就是避免了相同內容的字符串的創建,節省了內存,省去了創建相同字符串的時間,同時提升了性能;另一方面,字符串池的缺點就是犧牲了JVM在常量池中遍歷對象所需要的時間,不過其時間成本相比而言比較低。

     intern方法使用:一個初始為空的字符串池,它由類String獨自維護。當調用 intern方法時,如果池已經包含一個等于此String對象的字符串(用equals(oject)方法確定),則返回池中的字符串。否則,將此String對象添加到池中,并返回此String對象的引用。 對于任意兩個字符串s和t,當且僅當s.equals(t)為true時,s.instan() == t.instan才為true。所有字面值字符串和字符串賦值常量表達式都使用 intern方法進行操作。

     GC回收:字符串池中維護了共享的字符串對象,這些字符串不會被垃圾收集器回收。

     Java語言規范(Java Language Specification)中對字符串做出了如下說明:每一個字符串常量都是指向一個字符串類實例的引用。字符串對象有一個固定值。字符串常量,或者一般的說,常量表達式中的字符串都被使用方法 String.intern進行保留來共享唯一的實例。以上是Java語言規范中的原文,比較官方,用更通俗易懂的語言翻譯過來主要說明了三點:1)每一個字符串常量都指向字符串池中或者堆內存中的一個字符串實例;2)字符串對象值是固定的,一旦創建就不能再修改;3)字符串常量或者常量表達式中的字符串都被使用方法String.intern()在字符串池中保留了唯一的實例。并且給出了測試程序如下:

      如何進行Java字符串池String Pool的深度解析

    編譯單元:

    如何進行Java字符串池String Pool的深度解析

     輸出:

     如何進行Java字符串池String Pool的深度解析

     這個例子說明了6點:

  • 同一個包下同一個類中的字符串常量的引用指向同一個字符串對象;

  • 同一個包下不同的類中的字符串常量的引用指向同一個字符串對象;

  • 不同的包下不同的類中的字符串常量的引用仍然指向同一個字符串對象;

  • 由常量表達式計算出的字符串是在編譯時進行計算,然后被當作常量;

  • 在運行時通過連接計算出的字符串是新創建的,因此是不同的;

  • 通過計算生成的字符串顯示調用intern方法后產生的結果與原來存在的同樣內容的字符串常量是一樣的。

     從上面的例子可以看出,字符串常量在編譯時計算和在運行時計算,其執行過程是不同的,得到的結果也是不同的。我們來看看下面這段代碼:

     如何進行Java字符串池String Pool的深度解析

     代碼輸出如下:

     如何進行Java字符串池String Pool的深度解析

     為什么出現上面的結果呢?這是因為,字符串字面量拼接操作是在Java編譯器編譯期間就執行了,也就是說編譯器編譯時,直接把"java"、"language"和"specification"這三個字面量進行"+"操作得到一個"javalanguagespecification" 常量,并且直接將這個常量放入字符串池中,這樣做實際上是一種優化,將3個字面量合成一個,避免了創建多余的字符串對象。而字符串引用的"+"運算是在Java運行期間執行的,即str + str2 + str3在程序執行期間才會進行計算,它會在堆內存中重新創建一個拼接后的字符串對象。總結來說就是:字面量"+"拼接是在編譯期間進行的,拼接后的字符串存放在字符串池中;而字符串引用的"+"拼接運算實在運行時進行的,新創建的字符串存放在堆中。

     總結:字符串是常量,字符串池中的每個字符串對象只有唯一的一份,可以被多個引用所指向,避免了重復創建內容相同的字符串;通過字面值賦值創建的字符串對象存放在字符串池中,通過關鍵字new出來的字符串對象存放在堆中。

關于如何進行Java字符串池String Pool的深度解析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


本文題目:如何進行Java字符串池StringPool的深度解析
本文鏈接:http://m.jcarcd.cn/article/jjoeep.html
主站蜘蛛池模板: 日本丰满b | 乱伦视频| www亚洲伊| 九九自拍视频 | 日韩午夜特片 | 日本高清乱理 | 国产在线九色 | 精品在线播放 | 日本免费精品 | 国产va免费精 | 国产在线播放不卡 | 91视频入口| 日本精品大乳一区 | 国产原创精品在线 | 日本99成人免费 | 国产高清自拍在线 | 另类老熟女hd | 国产乡下妇女三片 | 日本高清不卡一区 | 欧美三级在线看 | 成人一区在线播放 | 日韩一级 | 九热官网 | 日本影片一区二区 | 国产在线高清理伦片 | 国产大片在线播放 | 日本高清视频不卡 | 日本aⅴ精品 | 福利免费视频在线 | 91最新福利 | 欧美亚洲下一页 | 18精品免费1区2 | 欧美亚洲日本 | 国产黄大片 | 品一二三产区 | 国产欧美一级精品 | 国产女女互摸互 | 日产亚洲一 | 日韩午夜剧场人畜 | 成人一区二区在线 | 国产精品有码 |