Java中String對象存儲

String對象 java

String s = new String(「xyz」);建立了兩個對象一個是「xyz」,一個是指向「xyz」的引用對象s。 數組

int i = 3;s=i+s;這個表達式對嗎?在java中會提示數據類型不匹配; spa

JAVA虛擬機(JVM)中存在着一個字符串池,其中保存着不少String對象,而且能夠被共享使用,所以它提升了效率。String a="abc";,這行代碼被執行的時候,JAVA虛擬機首先在字符串池中查找是否已經存在了值爲"abc"的這麼一個對象,判斷依據是Stringequals(Object obj)方法的返回值。若是有,則再也不建立新的對象,直接返回已存在對象的引用;若是沒有,則先建立這個對象,而後把它加入到字符串池中,再將它的引用返回。 對象

字符串對象的建立:因爲字符串對象的大量使用[它是一個對象,通常而言對象老是在heap分配內存]Java中爲了節省內存空間和運行時間[如比較字符串時,==equals()],在編譯階段就把全部的字符串文字放到一個文字池中,而運行時文字池成爲常量池的一部分。文字池的好處,就是該池中全部相同的字符串常量被合併,只佔用一個空間。咱們知道,對兩個引用變量,使用==判斷它們的值[引用]是否相等,即指向同一個對象 內存

如今看String s = new String("abc");語句,這裏"abc"自己就是pool中的一個對象,而在運行時執行new String()時,pool中的對象複製一份放到heap中,而且把heap中的這個對象的引用交給s持有 字符串

String s1 = new String("abc") ;String s2 = new String("abc") ;if( s1 == s2 ){ //不會執行的語句} 源碼

    //建立了幾個String Object? [三個,pool中一個,heap2] 虛擬機

只有使用引號包含文本的方式建立的String對象之間使用「+」鏈接產生的新對象纔會被加入字符串池中。對於全部包含new方式新建對象(包括null)的「+」鏈接表達式,它所產生的新對象都不會被加入字符串池中。  string

1.==表示引用自同一對象,equals()表示值相等。  編譯

String str1 = "abc";引用的對象在棧(或者叫String池)中。 

String str1 =new String ("abc"); 引用的對象在內存/堆中

2.String str1 =  "string";在棧中 

  String str3 =  "str";在棧中 

  String str4 = "ing";在棧中 

  String str2 = str3+str4; 在堆中,由於+號的做用是返回另一個新建的String對象,而不是在棧中找string這個值。若是是String str2 = "str"+"ing";那最後的結果就在棧中。str1==str2true

最後咱們再來講說String對象在JAVA虛擬機(JVM)中的存儲,以及字符串池與堆(heap)和棧(stack)的關係。咱們首先回顧一下堆和棧的區別: 

棧(stack):主要保存基本類型(或者叫內置類型)(charbyteshortintlongfloatdoubleboolean)和對象的引用,數據能夠共享,速度僅次於寄存器(register),快於堆。 

堆(heap):用於存儲對象。 

咱們查看String類的源碼就會發現,它有一個value屬性,保存着String對象的值,類型是char[],這也正說明了字符串就是字符的序列。當執行String a="abc";時,JAVA虛擬機會在棧中建立三個char型值'a''b''c',而後在堆中建立一個String對象它的值(value)是剛纔在棧中建立的三個char型值組成的數組{'a','b','c'}最後這個新建立的String對象會被添加到字符串池中

若是咱們接着執行String b=new String("abc");代碼,因爲"abc"已經被建立並保存於字符串池中,所以JAVA虛擬機只會在堆中新建立一個String對象,可是它的值(value)是共享前一行代碼執行時在棧中建立的三個char型值值'a''b''c'。 

說到這裏,咱們對於篇首提出的String str=new String("abc")爲何是建立了兩個對象這個問題就已經至關明瞭了。

相關文章
相關標籤/搜索