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

Java螞蟻發表於2019-07-26

面試官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引用的不是同一個字串地址。 記憶體結構圖如下:

 

從記憶體圖可見,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

版權:轉載請在文章明顯位置註明作者及出處。   

相關文章