2013-06-29 66 views
7
String str1="JAVA"; 
String str2="JAVA"; 
String str3=new String("JAVA"); 
String str4=new String("JAVA").intern(); 

將創建2個對象。 str1str2指相同的對象,因爲字符串文字池概念和str3指向新的對象,因爲使用新的運營商,並通過str1str4指向相同的物點和str2因爲intern()方法檢查到串池串具有相同的值。在此過程中創建的字符串對象的總數?

str1=str2=str3=str4=null; 

一個對象將有資格使用GC。這是通過String str3=new String("JAVA")創建的對象。第一個String對象始終可以通過存儲在字符串文字池中的引用訪問。

我的解釋是否正確?

回答

12

過程中創建的字符串對象的總數?

三:通過文字創建的實習生池中的一個和通過new String創建的兩個實體池。

一個對象將有資格使用GC。

我算兩個,甚至可能全部三個下非常特殊情況:

  1. 你在這行創建的一個:

    String str3=new String("JAVA"); 
    

    (因爲你以後設置str3null)。

  2. 你在這行創建暫時的一個:

    String str4=new String("JAVA").intern(); 
    

    這行創建了一個新的String對象,調用它intern,然後保存到從池中的字符串的引用。因此從理論上講,它創建了立即可用於GC的String對象。 (JVM可能足夠聰明而沒有這樣做,但這就是理論。)

  3. 可能最終在正確的條件下甚至是在實習生池中的字符串。與流行的看法相反,實習生池中的字符串爲,可用於垃圾回收,因爲我們可以從the answer to this other question中看到。僅僅因爲他們在傳染源(unless you're using Oracle's JVM 7 or later),並不意味着他們不是GC'd,因爲the permgen is GC'd too。所以問題就變成了:什麼時候或者如何在字符串中使用不再引用代碼?我不知道答案,但我認爲合理的假設會是:何時以及如果使用它的類是從內存中卸載的。根據this other answer,只有在類及其類加載程序都被卸載(並且可能不會發生)時纔會發生這種情況。如果這個類是由系統類加載器加載的(正常情況下),那麼它可能不會被卸載。

所以幾乎可以肯定只有兩個(上面的#1和#2),但是在#3中也很有趣。

+0

它們都設置爲null。不應該GC收集它們全部,因爲所有引用明確地設置爲'null'? – Maroun

+0

哦..沒有注意到:)咖啡的時間。 – Maroun

+0

我聽說實習字符串也是可收集的 - 它們永遠不會永久燙髮寶石 – dantuch