String對(duì)象有三種創(chuàng)建方式:
第一種方式是直接通過賦值語(yǔ)句,將字符串賦值給String類型的變量。
例如:
String str = “Hello”;
第二種方式是通過new運(yùn)算符,實(shí)例化一個(gè)String對(duì)象,并將對(duì)象引用賦值給String類型的變量。
例如:
String str = new String(“Hello”);
第三種方式是通過String對(duì)象的intern()方法返回一個(gè)String對(duì)象的引用。
例如:
String str = “Hello”。 intern();
前面String對(duì)象的三種創(chuàng)建方式,虛擬機(jī)對(duì)其內(nèi)存分配上是有所區(qū)別的,先來看第一種創(chuàng)建方式。
第一種創(chuàng)建方式是通過賦值語(yǔ)句直接將字符串賦值給String類型的變量。在這種創(chuàng)建方式中,虛擬機(jī)會(huì)在方法區(qū)的常量池中判斷是否存在具有和字符串(如Hello)內(nèi)容相同的String對(duì)象:如果常量池不存在和賦值字符串內(nèi)容相同的對(duì)象,虛擬機(jī)就在常量池中分配內(nèi)存并創(chuàng)建該String對(duì)象,并將String對(duì)象的引用賦值給String類型的變量;如果常量池存在與賦值字符串內(nèi)容相同的對(duì)象,虛擬機(jī)會(huì)直接將該對(duì)象的引用賦值給String類型的變量。這種創(chuàng)建方式對(duì)連續(xù)創(chuàng)建同一字符串內(nèi)容的String對(duì)象特別有用,內(nèi)存利用效率非常高效。
第二種創(chuàng)建方式是通過new運(yùn)算符實(shí)例化String對(duì)象,并將new運(yùn)算符返回的對(duì)象引用賦值給String類型的變量。在這種創(chuàng)建方式中,虛擬機(jī)會(huì)創(chuàng)建兩個(gè)String對(duì)象:一個(gè)String對(duì)象是在常量池中創(chuàng)建,如果常量池中已有字符串內(nèi)容相同的對(duì)象,則不創(chuàng)建;一個(gè)String對(duì)象是在運(yùn)行數(shù)據(jù)區(qū)的堆中創(chuàng)建,將在常量池中創(chuàng)建的String對(duì)象的字符數(shù)組復(fù)制到在堆中創(chuàng)建的String對(duì)象。
String類型的變量接收new運(yùn)算符返回的對(duì)象引用后,如果使用賦值語(yǔ)句對(duì)該String類型的變量重新賦予不同的字符串內(nèi)容,該變量將會(huì)指向一個(gè)新的String對(duì)象,該String對(duì)象會(huì)在常量池中創(chuàng)建。
案例1:建立StringTest1類,在類的main()方法內(nèi)部,使用new運(yùn)算符實(shí)例化一個(gè)String對(duì)象,返回的對(duì)象引用賦值給String類型的變量str,輸出str指向?qū)ο蟮墓4a,然后使用賦值語(yǔ)句將新的字符串內(nèi)容賦值給str,輸出str指向?qū)ο蟮墓4a,驗(yàn)證哈希碼是否一致。
在memory包下新建StringTest1類。代碼如下:
publicclassStringTest1 {
/**
* @Title: main
* @Description: Java程序入口main方法
* @returnvoid 返回類型
* @throws
*/
publicstaticvoidmain(String[] args) {
// 實(shí)例化String對(duì)象
String str = newString(“Hello”);
System.out.println(“str對(duì)象的哈希碼:” + str.hashCode());
// 修改str對(duì)象的內(nèi)容
str = “Hello World”;
System.out.println(“str對(duì)象修改后的哈希碼:” + str.hashCode());
}
}
程序執(zhí)行結(jié)果如下圖所示:
從程序的執(zhí)行結(jié)果可以看出,當(dāng)對(duì)str重新賦值不同的內(nèi)容后,虛擬機(jī)會(huì)在常量池創(chuàng)建一個(gè)新的String對(duì)象,并將該對(duì)象的引用賦值給str。
第三種創(chuàng)建方式是通過String對(duì)象的intern()方法來返回一個(gè)String對(duì)象的引用。在這種創(chuàng)建方式中,虛擬機(jī)會(huì)首先判斷在常量池中是否存在“Hello”字符串對(duì)象,如果存在就直接返回該對(duì)象的引用,否則就在常量池創(chuàng)建該對(duì)象,并返回對(duì)象的引用。
前面String對(duì)象的內(nèi)存分配經(jīng)常用到常量池,常量池是虛擬機(jī)從運(yùn)行數(shù)據(jù)區(qū)的方法區(qū)劃分出來的一塊內(nèi)存區(qū)域,JDK1.8將常量池放置到運(yùn)行數(shù)據(jù)區(qū)的堆區(qū)域。常量池主要用來存儲(chǔ)字面常量、使用final修飾的變量以及符號(hào)引用。字面常量包括數(shù)值常量(如36、100等)、字符串常量(如“123”、“abc”等)。符號(hào)引用是指用一組符號(hào)來描述引用的目標(biāo),符號(hào)可以是任何形式的字面量,只要使用時(shí)能夠無歧義的定位到目標(biāo)即可。例如編譯器會(huì)把對(duì)象的引用作為一個(gè)符號(hào)引用,因?yàn)榫幾g器不知道對(duì)象引用在內(nèi)存的實(shí)際地址,當(dāng)虛擬機(jī)加載類到運(yùn)行數(shù)據(jù)區(qū)并初始化類后,虛擬機(jī)會(huì)把這些符號(hào)引用轉(zhuǎn)換為直接引用(指向目標(biāo)的內(nèi)存地址,如對(duì)象在堆中的內(nèi)存地址)。
-
JAVA
+關(guān)注
關(guān)注
19文章
2969瀏覽量
104780 -
內(nèi)存分配
+關(guān)注
關(guān)注
0文章
16瀏覽量
8307 -
string
+關(guān)注
關(guān)注
0文章
40瀏覽量
4735
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論