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ù)組復制到在堆中創(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方法
* @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é)果可以看出,當對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”等)。符號引用是指用一組符號來描述引用的目標,符號可以是任何形式的字面量,只要使用時能夠無歧義的定位到目標即可。例如編譯器會把對象的引用作為一個符號引用,因為編譯器不知道對象引用在內(nèi)存的實際地址,當虛擬機加載類到運行數(shù)據(jù)區(qū)并初始化類后,虛擬機會把這些符號引用轉(zhuǎn)換為直接引用(指向目標的內(nèi)存地址,如對象在堆中的內(nèi)存地址)。
-
JAVA
+關(guān)注
關(guān)注
19文章
2967瀏覽量
104758 -
內(nèi)存分配
+關(guān)注
關(guān)注
0文章
16瀏覽量
8307 -
string
+關(guān)注
關(guān)注
0文章
40瀏覽量
4735
發(fā)布評論請先 登錄
相關(guān)推薦
評論