0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳解String對象的內(nèi)存分配

如意 ? 來源:百家號 ? 作者:米粒教育 ? 2020-07-01 10:09 ? 次閱讀

String對象有三種創(chuàng)建方式:

第一種方式是直接通過賦值語句,將字符串賦值給String類型的變量。

例如:

String str = “Hello”;

第二種方式是通過new運算符,實例化一個String對象,并將對象引用賦值給String類型的變量。

例如:

String str = new String(“Hello”);

第三種方式是通過String對象的intern()方法返回一個String對象的引用。

例如:

String str = “Hello”。 intern();

前面String對象的三種創(chuàng)建方式,虛擬機對其內(nèi)存分配上是有所區(qū)別的,先來看第一種創(chuàng)建方式。

第一種創(chuàng)建方式是通過賦值語句直接將字符串賦值給String類型的變量。在這種創(chuàng)建方式中,虛擬機會在方法區(qū)的常量池中判斷是否存在具有和字符串(如Hello)內(nèi)容相同的String對象:如果常量池不存在和賦值字符串內(nèi)容相同的對象,虛擬機就在常量池中分配內(nèi)存并創(chuàng)建該String對象,并將String對象的引用賦值給String類型的變量;如果常量池存在與賦值字符串內(nèi)容相同的對象,虛擬機會直接將該對象的引用賦值給String類型的變量。這種創(chuàng)建方式對連續(xù)創(chuàng)建同一字符串內(nèi)容的String對象特別有用,內(nèi)存利用效率非常高效。

第二種創(chuàng)建方式是通過new運算符實例化String對象,并將new運算符返回的對象引用賦值給String類型的變量。在這種創(chuàng)建方式中,虛擬機會創(chuàng)建兩個String對象:一個String對象是在常量池中創(chuàng)建,如果常量池中已有字符串內(nèi)容相同的對象,則不創(chuàng)建;一個String對象是在運行數(shù)據(jù)區(qū)的堆中創(chuàng)建,將在常量池中創(chuàng)建的String對象的字符數(shù)組復(fù)制到在堆中創(chuàng)建的String對象。

String類型的變量接收new運算符返回的對象引用后,如果使用賦值語句對該String類型的變量重新賦予不同的字符串內(nèi)容,該變量將會指向一個新的String對象,該String對象會在常量池中創(chuàng)建。

案例1:建立StringTest1類,在類的main()方法內(nèi)部,使用new運算符實例化一個String對象,返回的對象引用賦值給String類型的變量str,輸出str指向?qū)ο蟮墓4a,然后使用賦值語句將新的字符串內(nèi)容賦值給str,輸出str指向?qū)ο蟮墓4a,驗證哈希碼是否一致。

在memory包下新建StringTest1類。代碼如下:

publicclassStringTest1 {

/**

* @Title: main

* @Description: Java程序入口main方法

* @param@paramargs 參數(shù)

* @returnvoid 返回類型

* @throws

*/

publicstaticvoidmain(String[] args) {

// 實例化String對象

String str = newString(“Hello”);

System.out.println(“str對象的哈希碼:” + str.hashCode());

// 修改str對象的內(nèi)容

str = “Hello World”;

System.out.println(“str對象修改后的哈希碼:” + str.hashCode());

}

}

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

從程序的執(zhí)行結(jié)果可以看出,當(dāng)對str重新賦值不同的內(nèi)容后,虛擬機會在常量池創(chuàng)建一個新的String對象,并將該對象的引用賦值給str。

第三種創(chuàng)建方式是通過String對象的intern()方法來返回一個String對象的引用。在這種創(chuàng)建方式中,虛擬機會首先判斷在常量池中是否存在“Hello”字符串對象,如果存在就直接返回該對象的引用,否則就在常量池創(chuàng)建該對象,并返回對象的引用。

前面String對象的內(nèi)存分配經(jīng)常用到常量池,常量池是虛擬機從運行數(shù)據(jù)區(qū)的方法區(qū)劃分出來的一塊內(nèi)存區(qū)域,JDK1.8將常量池放置到運行數(shù)據(jù)區(qū)的堆區(qū)域。常量池主要用來存儲字面常量、使用final修飾的變量以及符號引用。字面常量包括數(shù)值常量(如36、100等)、字符串常量(如“123”、“abc”等)。符號引用是指用一組符號來描述引用的目標(biāo),符號可以是任何形式的字面量,只要使用時能夠無歧義的定位到目標(biāo)即可。例如編譯器會把對象的引用作為一個符號引用,因為編譯器不知道對象引用在內(nèi)存的實際地址,當(dāng)虛擬機加載類到運行數(shù)據(jù)區(qū)并初始化類后,虛擬機會把這些符號引用轉(zhuǎn)換為直接引用(指向目標(biāo)的內(nèi)存地址,如對象在堆中的內(nèi)存地址)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2952

    瀏覽量

    104479
  • 內(nèi)存分配
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    8292
  • string
    +關(guān)注

    關(guān)注

    0

    文章

    40

    瀏覽量

    4715
收藏 人收藏

    評論

    相關(guān)推薦

    詳解單片機的內(nèi)存分配

    對于初學(xué)者而言,對單片機的內(nèi)存分配往往最讓人頭疼,很多人學(xué)了單片機幾年 都不知道單片機內(nèi)部的內(nèi)存使用情況是如何分配的。要了解 ROM(flash)、RAM(sram)啟動,首先 需要對
    發(fā)表于 11-07 10:42 ?2250次閱讀

    C語言既然可以自動為變量分配內(nèi)存,為什么還要用動態(tài)分配內(nèi)存呢?

    不知道大家在學(xué)習(xí)C語言動態(tài)分配內(nèi)存的時候有沒有過這樣的疑問,既然系統(tǒng)可以自動幫我們分配內(nèi)存,為什么還需要我們程序員自己去分配
    發(fā)表于 12-13 11:14 ?986次閱讀

    單片機的內(nèi)存分配詳解

    對于初學(xué)者而言,對單片機的內(nèi)存分配往往最讓人頭疼,很多人學(xué)了單片機幾年 都不知道單片機內(nèi)部的內(nèi)存使用情況是如何分配的。要了解 ROM、RAM啟動,首先 需要對 鏈接器 Linker 如
    發(fā)表于 03-05 15:00

    對象分配內(nèi)存錯誤怎么辦

    請大神幫忙,萬分感謝!?。〔僮飨到y(tǒng):ucosIII 芯片:STM32F103我的類建立比較多。類對象是指針CCarriage*gCar;分配內(nèi)存語句:gCar = new CCarriage
    發(fā)表于 05-25 09:51

    Linux內(nèi)存系統(tǒng): Linux 內(nèi)存分配算法

    內(nèi)核中經(jīng)常使用的對象放到高速緩存中,并且由系統(tǒng)保持為初始的可利用狀態(tài)。比如進程描述符,內(nèi)核中會頻繁對此數(shù)據(jù)進行申請和釋放2) 內(nèi)部碎片· 已經(jīng)被分配出去的的內(nèi)存空間大于請求所需的內(nèi)存
    發(fā)表于 08-24 07:44

    請問JavaScript字符串對象String是什么?

    字符串對象 String 提供了對字符串進行處理的屬性和方法
    發(fā)表于 11-05 06:39

    關(guān)于RTT支持的內(nèi)存分配算法

    的融合。 最原始的SLAB算法是Jeff Bonwick為Solaris 操作系統(tǒng)而引入的一種高效內(nèi)核內(nèi)存分配算法。 RT-Thread的SLAB分配器實現(xiàn)主要是去掉了其中的對象構(gòu)造及
    發(fā)表于 04-27 14:40

    關(guān)于RTT支持的內(nèi)存分配算法

    的融合。 最原始的SLAB算法是Jeff Bonwick為Solaris 操作系統(tǒng)而引入的一種高效內(nèi)核內(nèi)存分配算法。 RT-Thread的SLAB分配器實現(xiàn)主要是去掉了其中的對象構(gòu)造及
    發(fā)表于 04-27 14:42

    java中string不可變的原因

    ABCabc, 然后又讓s的值為123456。 從打印結(jié)果可以看出,s的值確實改變了。那么怎么還說String對象是不可變的呢? 其實這里存在一個誤區(qū): s只是一個String對象的引
    發(fā)表于 09-27 13:24 ?0次下載
    java中<b class='flag-5'>string</b>不可變的原因

    一文詳解Java對象內(nèi)存布局

    這個實例對象是以怎樣的形態(tài)存在內(nèi)存中的? 一個Object對象內(nèi)存中占用多大? 對象中的屬性是如何在內(nèi)
    發(fā)表于 09-30 14:38 ?1190次閱讀
    一文<b class='flag-5'>詳解</b>Java<b class='flag-5'>對象</b>的<b class='flag-5'>內(nèi)存</b>布局

    什么是堆內(nèi)存?堆內(nèi)存是如何分配的?

    在一般的編譯系統(tǒng)中,堆內(nèi)存分配方向和棧內(nèi)存是相反的。當(dāng)棧內(nèi)存從高地址向低地址增長的時候,堆內(nèi)存從低地址向高地址
    的頭像 發(fā)表于 07-05 17:58 ?9895次閱讀

    字符串string對象操作的全面總結(jié)

    ? ? 字符串操作看似簡單,其實非常重要,不注意的話,經(jīng)常出現(xiàn)代碼運行結(jié)果和自己想要的不一致,甚至崩潰。本文總結(jié)了一些構(gòu)建string對象方法、修改string對象的方法、
    的頭像 發(fā)表于 11-11 11:23 ?1901次閱讀
    字符串<b class='flag-5'>string</b><b class='flag-5'>對象</b>操作的全面總結(jié)

    單片機的內(nèi)存分配(變量的存儲位置)詳解

    對于初學(xué)者而言,對單片機的內(nèi)存分配往往最讓人頭疼,很多人學(xué)了單片機幾年 都不知道單片機內(nèi)部的內(nèi)存使用情況是如何分配的。要了解 ROM、RAM啟動,首先 需要對 鏈接器 Linker 如
    發(fā)表于 12-31 19:47 ?2次下載
    單片機的<b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>(變量的存儲位置)<b class='flag-5'>詳解</b>

    linux內(nèi)存管理中的SLAB分配詳解

    管理區(qū)頁框分配器,這里我們簡稱為頁框分配器,在頁框分配器中主要是管理物理內(nèi)存,將物理內(nèi)存的頁框分配
    發(fā)表于 05-17 15:01 ?2164次閱讀
    linux<b class='flag-5'>內(nèi)存</b>管理中的SLAB<b class='flag-5'>分配</b>器<b class='flag-5'>詳解</b>

    bigdecimal轉(zhuǎn)string類型

    情況下,我們可能需要將BigDecimal對象轉(zhuǎn)換為String類型,例如在進行數(shù)據(jù)的持久化、傳輸、展示等場景中。下面將詳細介紹如何在Java中將BigDecimal轉(zhuǎn)換為String類型。 在Java
    的頭像 發(fā)表于 11-30 11:09 ?6190次閱讀