1. 程式人生 > >String str = new String("abc")究竟建立了幾個物件?

String str = new String("abc")究竟建立了幾個物件?

先給出答案:兩個。(如果原來常量池中沒有"abc")

 

String是一個特殊的包裝類資料。即可以用String str = new String("abc");的形式來建立,也可以用String str = "abc";的形式來建立

String str = "abc"建立物件的過程

 

  1. 首先在常量池中查詢是否存在內容為"abc"字串物件
  2. 如果不存在則在常量池中建立"abc",並讓str引用該物件
  3. 如果存在則直接讓str引用該物件


"abc"是怎麼儲存,儲存在哪?

常量池屬於類資訊的一部分,而類資訊反映到JVM記憶體模型中是對應存在於JVM記憶體模型的方法區,也就是說這個類資訊 中的常量池概念是存在於在方法區中。

而方法區是在JVM記憶體模型中的堆中由JVM來分配的,所以"abc"可以說存在於堆中(而有些資料,為了把方法區的 堆區別於JVM的堆,把方法區稱為棧)。一般這種情況下,"abc"在編譯時就被寫入位元組碼中,所以class被載入時,JVM就為"abc"在常量池中 分配記憶體,所以和靜態區差不多。


String str = new String("abc")建立例項的過程

 

  1. 首先在堆中(不是常量池)建立一個指定的物件"abc",並讓str引用指向該物件
  2. 在字串常量池中檢視,是否存在內容為"abc"字串物件
  3. 若存在,則將new出來的字串物件與字串常量池中的物件聯絡起來
  4. 若不存在,則在字串常量池中建立一個內容為"abc"的字串物件,並將堆中的物件與之聯絡起來

 

我們來看以下兩個例子加深理解:

String str1 = "abc"; String str2 = "ab" + "c"; str1==str2是true嗎?

答案:是。因為String str2 = "ab" + "c"會查詢常量池中時候存在內容為"abc"字串物件,如存在則直接讓str2引用該物件,顯然String str1 = "abc"的時候,上面說了,會在常量池中建立"abc"物件,所以str1引用該物件,str2也引用該物件,所以str1==str2

 

String str1 = "abc"; String str2 = "ab"; String str3 = str2 + "c"; str1==str3是false嗎?

答案:是。因為String str3 = str2 + "c"涉及到變數(不全是常量)的相加,所以會生成新的物件,其內部實現是先new一個StringBuilder,然後 append(str2),append("c");然後讓str3引用toString()返回的物件