国产睡熟迷奷白丝护士系列精品,中文色字幕网站,免费h网站在线观看的,亚洲开心激情在线

      <sup id="hb9fh"></sup>
          1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

            手機(jī)站
            千鋒教育

            千鋒學(xué)習(xí)站 | 隨時隨地免費學(xué)

            千鋒教育

            掃一掃進(jìn)入千鋒手機(jī)站

            領(lǐng)取全套視頻
            千鋒教育

            關(guān)注千鋒學(xué)習(xí)站小程序
            隨時隨地免費學(xué)習(xí)課程

            當(dāng)前位置:首頁  >  技術(shù)干貨  > String字符串常量池和intern方法

            String字符串常量池和intern方法

            來源:千鋒教育
            發(fā)布人:zyh
            時間: 2023-06-13 17:50:00 1686649800

              全文大約【2300】字,不說廢話,只講可以讓你學(xué)到技術(shù)、明白原理的純干貨!本文帶有豐富的案例及配圖視頻,讓你更好地理解和運用文中的技術(shù)概念,并可以給你帶來具有足夠啟迪的思考......

            String字符串常量池和intern方法

              一. 常量池簡介

              1.基本概念

              常量池是堆中的一塊存儲區(qū)域,用于存儲顯式的String、float、Integer等數(shù)據(jù)。這是一個特殊的共享區(qū)域,開發(fā)時不需要在內(nèi)存中經(jīng)常改變的數(shù)據(jù),都可以放在這里進(jìn)行共享。JDK 7及其之前的常量池是在方法區(qū)中,從Java8之后,常量池存放到了堆中。

              為了讓大家更好地理解常量池的作用,壹哥給大家分析一下String字符串的內(nèi)存分配。

              2.實驗案例

              我們先來編寫一行代碼,如下所示: 

            //String對象創(chuàng)建
            String s = new String("xyz");

              這個代碼很簡單,就一行代碼!那么問題來了,這行代碼中幾個對象的內(nèi)存分配是如何的?接下來壹哥就給大家把這段代碼的內(nèi)存分區(qū)繪制一下(本案例開發(fā)環(huán)境是基于JDK8)。

              3. 內(nèi)存分配(重點)

              在 String s = new String("xyz"); 這行代碼中,s是String類型的變量,不是對象!‘xyz’是字符串對象,new String("xyz")也是一個對象,那么它們幾個的內(nèi)存劃分在JDK8的環(huán)境中,如下圖所示:

            1683284545263.image

                  根據(jù)上圖,壹哥給大家分析一下上述代碼的內(nèi)存分配情況,如下所示:

              1.當(dāng)JVM在編譯階段加載讀取到“xyz”的時候,首先會檢查堆中的String常量池,也就是常量緩沖區(qū)。檢查是否已經(jīng)有了"xyz"常量對象,如果有,則不會再次創(chuàng)建"xyz"常量對象,并直接返回該字符串的引用地址;如果沒有,則創(chuàng)建一個"xyz"常量對象,并為該對象分配一個內(nèi)存地址002返回;

              2.當(dāng)JVM在運行階段加載讀取到new關(guān)鍵字的時候,JVM會在堆中為其創(chuàng)建一個對象,即new String(),并為其分配內(nèi)存地址001,而堆中這個對象的內(nèi)容是上面"xyz"常量對象的引用地址002,換句話說這個堆中存的就是常量池中"xyz"的引用地址002;

              最后,s 是對當(dāng)前堆中001號對象的一個地址引用,s本身不是一個對象,s只是一個String類型的變量而已!

              二. intern()方法(重點)

              了解了常量池的內(nèi)容之后,接下來請大家再跟著壹哥來看看String的intern()方法,這個方法很重要,請大家記住哦。 

            /**
            * Returns a canonical representation for the string object.
            * <p>
            * A pool of strings, initially empty, is maintained privately by the
            * class {@code String}.
            * <p>
            * When the intern method is invoked, if the pool already contains a
            * string equal to this {@code String} object as determined by
            * the {@link #equals(Object)} method, then the string from the pool is
            * returned. Otherwise, this {@code String} object is added to the
            * pool and a reference to this {@code String} object is returned.
            * <p>
            * It follows that for any two strings {@code s} and {@code t},
            * {@code s.intern() == t.intern()} is {@code true}
            * if and only if {@code s.equals(t)} is {@code true}.
            * <p>
            * All literal strings and string-valued constant expressions are
            * interned. String literals are defined in section 3.10.5 of the
            * <cite>The Java&trade; Language Specification</cite>.
            *
            * @return a string that has the same contents as this string, but is
            * guaranteed to be from a pool of unique strings.
            */
            public native String intern();

              從上面的源碼注釋中我們可以知道,intern()是由C語言實現(xiàn)的native底層方法,用于從String緩存池中獲取一個與該字符串內(nèi)容相同的字符串對象。當(dāng)這個intern()方法被執(zhí)行的時候,如果緩存池中已經(jīng)有這個String內(nèi)容,則直接從這個緩存池中獲取該String內(nèi)容對象;如果緩存池中沒有這個String內(nèi)容對象,則把這個String內(nèi)容對象放到緩存池中,并返回這個字符串對象的引用?,F(xiàn)在我們知道了intern()方法的功能,但是該方法的底層原理是什么樣的呢?接下來 壹哥 給結(jié)合一段代碼案例,給各位詳細(xì)說一下:  

            //常量池與堆的關(guān)系
            String str1="yiyige";
            String str2=new String("yiyige");
            System.out.println("str1==str2的結(jié)果==> " +(str1==str2));

            String str3 = str2.intern();
            System.out.println("str1==str3的結(jié)果==> " +(str1==str3));

              執(zhí)行結(jié)果如下圖所示:

            1683284585930.image

              intern()方法的底層原理如下(重點):

              Java專門為String類設(shè)計了一個緩存池intern pool,intern pool是在方法區(qū)中的一塊特殊存儲區(qū)域,當(dāng)我們通過 String str="yiyige" 這樣的方式來構(gòu)造一個新的字符串時,String類會優(yōu)先在緩存池中查找是否已經(jīng)存在內(nèi)容相同的String對象。如果有則直接返回該對象的地址引用,如果沒有就會構(gòu)造一個新的String對象,然后放進(jìn)緩存池,再返回該字符串的地址引用。因此,即使我們構(gòu)造一萬個String str = "yiyige",但實際上得到的都是同一個地址引用,這樣就避免了很多不必要的空間開銷。注意:intern池不適用new String("yiyige")的構(gòu)造形式!

              注意:

              因為字符串常量池存放位置發(fā)生了變化,String類對intern()方法也進(jìn)行了一些修改:

              JDK 6 版本中執(zhí)行intern()方法時,首先會判斷字符串常量池中是否存在該字符串字面量,如果不存在則拷貝一份字符串字面量存放到常量池中,最后返回該字符串字面量的唯一引用。如果發(fā)現(xiàn)字符串常量池中已經(jīng)存在,則直接返回該字符串字面量的唯一引用。

              JDK 7 以后執(zhí)行intern()方法時,如果發(fā)現(xiàn)字符串常量池中不存在該字符串字面量,則不會再拷貝一份字面量,而是拷貝字面量對應(yīng)堆中的一個地址引用,然后返回這個引用。

              現(xiàn)在我們知道了,原來當(dāng)一個String對象被創(chuàng)建時,如果發(fā)現(xiàn)當(dāng)前String對象已經(jīng)存在于String Pool中了,就會返回一個已存在的String對象引用而不會新建一個對象。比如以下代碼只會在常量池中創(chuàng)建一個String對象。  

            String str1 = "yiyige"; 
            String str2 = "yiyige";

               創(chuàng)建過程如下圖所示:

            1683284610520.image

              如果一個String是可變的,當(dāng)改變了A引用指向的String時,可能就會導(dǎo)致其他的B引用得到錯誤的值,所以Sting就被設(shè)計為不可變的。String底層主要是使用intern緩存池將字符串緩存起來,同時允許把一個String字符串的地址賦值給多個String變量來引用,這樣就可以保證多個變量安全地共享同一個對象。如果Java中的String對象可變的話,一個字符串引用的操作改變了對象的值,那么其他的變量就會受到影響。

            聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
            10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
            請您保持通訊暢通,專屬學(xué)習(xí)老師24小時內(nèi)將與您1V1溝通
            免費領(lǐng)取
            今日已有369人領(lǐng)取成功
            劉同學(xué) 138****2860 剛剛成功領(lǐng)取
            王同學(xué) 131****2015 剛剛成功領(lǐng)取
            張同學(xué) 133****4652 剛剛成功領(lǐng)取
            李同學(xué) 135****8607 剛剛成功領(lǐng)取
            楊同學(xué) 132****5667 剛剛成功領(lǐng)取
            岳同學(xué) 134****6652 剛剛成功領(lǐng)取
            梁同學(xué) 157****2950 剛剛成功領(lǐng)取
            劉同學(xué) 189****1015 剛剛成功領(lǐng)取
            張同學(xué) 155****4678 剛剛成功領(lǐng)取
            鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
            董同學(xué) 138****2867 剛剛成功領(lǐng)取
            周同學(xué) 136****3602 剛剛成功領(lǐng)取
            相關(guān)推薦HOT
            PUE是什么?

            一、PUE是什么PUE,即功耗比(Power Usage Effectiveness),是數(shù)據(jù)中心的能源效率指標(biāo)。它是數(shù)據(jù)中心總功耗與設(shè)備功耗的比值,用于評估數(shù)據(jù)中...詳情>>

            2023-10-15 07:13:07
            graph cut和graph cuts有什么區(qū)別?

            1.語境不同graph cut”通常在描述一個操作時使用,比如”perform a graph cut”,它指的是在圖中找到一個切割,將圖劃分為兩個...詳情>>

            2023-10-15 07:02:16
            什么是雙機(jī)熱備?

            一、雙機(jī)熱備的原理雙機(jī)熱備是指在系統(tǒng)中配置兩臺服務(wù)器(主服務(wù)器和備份服務(wù)器),兩者通過高速網(wǎng)絡(luò)連接進(jìn)行實時數(shù)據(jù)同步和狀態(tài)同步。主服務(wù)器...詳情>>

            2023-10-15 06:37:02
            偏最小二乘支持向量機(jī)和支持向量機(jī)回歸的區(qū)別是什么?

            1.模型構(gòu)建的理論基礎(chǔ)不同支持向量機(jī)回歸(SVR)基于統(tǒng)計學(xué)習(xí)理論,其主要思想是找到一個超平面,使得大部分?jǐn)?shù)據(jù)點都在這個超平面的一定范圍內(nèi),...詳情>>

            2023-10-15 06:30:45
            VAE、GAN和transformer有什么區(qū)別?

            1.模型結(jié)構(gòu)不同VAE(變分自編碼器)是一種生成模型,其基于概率圖模型和自編碼器,能夠?qū)W習(xí)數(shù)據(jù)的潛在分布。GAN(生成對抗網(wǎng)絡(luò))同樣是一種生成...詳情>>

            2023-10-15 06:10:12