String s = new String(123) 究竟創建了幾個對象

前言

今天上班划水的過程中有人詢問到這個問題,網上對於這個問題也有爭議,有說創建了一個對象,有說兩個,有說三個。

首先說三個的肯定是扯淡了,今天來討論一下這條語句到底創建了幾個對象。

在進入正題之前,先回顧一下幾個基礎知識。

常量池

常量池是爲了避免對對象的重複創建和銷燬而影響系統性能,從而實現對象共享。在編譯期就能確定的字符串,會被存放到常量池中,如String s = "123";。此後如果使用到123這個字符串,就會直接從常量池中獲取,而不用每次都再new一個123出來。關於常量池更詳細的知識點,請閱讀這篇文章 Java常量池

對象比較

==和equals的區別想必就不需要我着重介紹了,equals比較的是值,==比較引用類型時,比較的是地址。

進入正題

稍微介紹了一下上面兩個基礎知識點,下面進入正題,String s = new String("123")究竟創建了幾個對象?這裏先說結論,第一次創建了兩個,第二次創建了一個。

我們來分析這條語句。首先s是一個引用變量,用來接收new的String,因此s不是一個對象。new String是典型的創建一個對象,放到堆中。而"123"也是個對象,123在編譯期就可以確定,因此是放到常量池。上面這句代碼可以拆成下面兩條。

String temp = "123";
String s = new String(temp);

這樣就很容易理解了,String temp = "123"毫無疑問是創建了一個對象,new String(temp)又創建了一個對象,因此是兩個。

那麼創建一個對象的結論是從何而來的?

首先來通過代碼證明一下常量池是否存在。

String s1 = "123";
String s2 = "123";
System.out.println(s1 == s2);

s1和s2都是字符串對象,通過==比較的是二者地址,運行結果爲true,說明二者地址相同,是同一個對象。

在 String s1 = "123";這條語句中,創建了一個對象"123",放入常量池中,下面的String s2 = "123";從常量池中取出了123並賦值給s2,因此s2這條語句沒有創建對象。

那麼我們看下面的代碼。

String temp = "123";
String s1 = new String(temp);

String temp2 = "123";
String s2 = new String(temp2);

在這個代碼中,上面的代碼創建了兩個對象,分別是"123"和new String("123"),接着, 123被存入常量池中。下面的代碼取出123並new String("123"),只創建了一個對象。

結語

在 String s = new String("123") 這條語句中

當常量池中不存在123時,創建了兩個對象。

當常量池中存在123時,創建了一個對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章