【JDK】分析 String str=““ 與 new String()

風塵部落格發表於2021-09-18

一、基礎概念

為了講清楚他們的差異,這裡先介紹幾個概念。

1.1 常量池

所謂常量池:顧名思義就是用來存放一些常量的。該常量是在編譯期被確定,並被儲存在已編譯的.class檔案中,其中包括了類,方法,介面等包含的數值常量,字元常量和字串常量。

1.2 字串常量池

在常量池中,有個專門用來儲存字串常量的,稱之為字串常量池。

當我們需要使用字串時,首先會在該字串常量中查詢是否存在該字串,若存在則直接進行使用;若不存在,則會新建一個對應的字串,並儲存在該字串常量池中。

1.3 在編譯期間建立的常量和執行期間建立的常量儲存的地址是不一樣的

物件的引用都是存放在棧中

  1. 編譯期間建立的常量儲存在常量池中;
  2. 執行期間通過new建立時,會直接建立一個新字串常量並會儲存在堆中。

所以我們可以發現,在堆中,可以有很多重複相同的字串,而在常量池中,不會出現重複的值。

1.4 equals()==

  • ==
  1. 如果是基本型別,==表示判斷它們值是否相等;
  2. 如果是引用物件,==表示判斷兩個物件指向的記憶體地址是否相同。
  • equals()
  1. equals()方法未被重寫時(Object時),比較的是記憶體地址;
  2. equals()方法被StringIntegerDate等類重寫時,其比較的是兩個內容是否相同。

二、String str=""new String()的區別

2.1 String str=""

例如:

String str = "風塵部落格";
  • 先在棧區建立str引用,然後關於建立物件。

這個表示式,可能會建立一個物件,也可能不會建立物件。

  1. 如果常量池中沒有“風塵部落格”這個字串,就需要建立;
  2. 常量池中存在“風塵部落格"這個字串,就直接拿來用。
  • 最後str指向常量池中的物件。

注意!這裡就是上面說的,從常量池中直接取用,所以,兩者引用地址應該也相同,即 == 比較為true
JDK-String-compare-01

2.2 String str=new String()

String str=new String(“風塵部落格”)
  • 同樣的,先在棧區建立str引用;

這個表示式,可能會建立一個物件,也可能建立兩個物件。

  1. 然後會直接建立一個字串存放在堆中;
  2. 其次,同樣的:如果常量池中沒有“風塵部落格”這個字串,就需要建立;常量池中存在“風塵部落格"這個字串,就直接拿來用。
  • 最後str指向常量池中的物件。

注意!這裡這裡和上面不一樣,這裡直接在堆裡建立物件,每新建一個都會建立一個,所以,兩者引用地址肯定不相同,即 == 比較為false

JDK-String-compare-02

相關文章