JAVA面試題 String s = new String("xyz");產生了幾個對象?

面試官Q1:請問String s = new String("xyz");產生了幾個對象?

對於這個Java面試題,老套路先上代碼:

public class StringTest {
 public static void main(String[] args){
 String s1="Hello";
 String s2="Hello";
 String s3=new String("Hello");
 System.out.println("s1和s2 引用地址是否相同:"+(s1 == s2));
 System.out.println("s1和s2 值是否相同:"+s1.equals(s2));
 System.out.println("s1和s3 引用地址是否相同:"+(s1 == s3));
 System.out.println("s1和s3 值是否相同:"+s1.equals(s3));
 }
}

打印結果如下:

s1和s2 引用地址是否相同:true
s1和s2 值是否相同:true
s1和s3 引用地址是否相同:false
s1和s3 值是否相同:true

上面程序中的"=="是判斷兩個對象引用的地址是否相同,也就是判斷是否為同一個對象,s1與s2 返回為true,s1與s3返回則是false。說明s1與s2 引用的同一個對象的地址,s3則與其它兩個引用不是同一個對象地址。

Java為了避免產生大量的String對象,設計了一個字符串常量池。工作原理是這樣的,創建一個字符串時,JVM首先為檢查字符串常量池中是否有值相等的字符串,如果有,則不再創建,直接返回該字符串的引用地址,若沒有,則創建,然後放到字符串常量池中,並返回新創建的字符串的引用地址。所以上面s1與s2引用地址相同。

那為什麼s3與s1、s2引用的不是同一個字符串地址呢? String s3=new String("Hello"); JVM首先是在字符串常量池中找"Hello" 字符串,如果沒有創建字符串常量,然後放到常量池中,若已存在,則不需要創建;當遇到 new 時,還會在內存(不是字符串常量池中,而是在堆裡面)上創建一個新的String對象,存儲"Hello",並將內存上的String對象引用地址返回,所以s3與s1、s2引用的不是同一個字符串地址。 內存結構圖如下:

JAVA面試題 String s = new String(

從內存圖可見,s1與s2指向的都是常量池中的字符串常量,所以它們比較的是同一塊內存地址,而s3指向的是堆裡面的一塊地址,說的具體點應該是堆裡面的Eden區域,s1跟s3,s2跟s3比較都是不相等的,都不是同一塊地址。

瞭解了String類的工作原理,迴歸問題本身:

在String的工作原理中,已經提到了,new一個String對象,是需要先在字符串常量中查找相同值或創建一個字符串常量,然後再在內存中創建一個String對象,所以String str = new String("xyz"); 會創建兩個對象。

下面兩道Java面試題可以放在留言區回覆喲:


String str1 = new String("A"+"B") ; 會創建多少個對象?

String str2 = new String("ABC") + "ABC" ; 會創建多少個對象?

作者:Java螞蟻

出處:https://www.cnblogs.com/marsitman/p/11248001.html


分享到:


相關文章: