2010-06-02 57 views
5

考慮下面的代碼何時創建/銷燬常量字符串?

public static void method(String[] srgs){ 
try{ 

}catch(){ 
System.out.println("Hello World" + "one");} 
catch(..){ 
System.out.println("Hello World" + "two");} 
catch(..){ 
System.out.println(getString());} 
} 
  1. 在這些字符串創建時?我假設在運行時發生異常時,字符串會被創建。該字符串在運行時創建並顯示。我的同行告訴我,由於這些是不變的字符串,只要Class加載,它們就會被創建。那是對的嗎?

  2. 何時收集了字符串垃圾?他們是否收集垃圾?假設同樣的方法可能會在程序生命週期中被多次調用,那麼緩存它們沒有意義嗎?

回答

6
  1. 這些字符串實際上恆定字符串和將在類的常量池,因此將在JVM被加載類時被實例化。它們是用+創建的這一事實並不重要,因爲整個字符串仍然是一個常量表達式(即它將與您寫入"Hello Worldone""Hello Worldtwo"時完全相同)。這些規則在JLS的§ 3.10.5 String Literals中描述。

  2. String對象被垃圾收集的方式與其他任何對象都是垃圾收集一樣,對他們來說沒有任何內在的不同。 但是some String are interned(最值得注意的是這包括所有的字符串文字),這可能會或可能不會阻止它們被垃圾收集(這沒有定義,並且取決於實現)。

    所以只要你的類保持加載,那些字符串常量將保持存在,不會被垃圾收集。

+0

感謝約阿希姆,考慮SOP(的 「Hello World」 + getstr()),在這種情況下常量字符串仍然創造出來的?當這行被執行時是第二個字符串創建?第二個字符串垃圾是否被收集?你能否給我一個來自你回答第1點的來源。 – Geek 2010-06-02 10:39:12

+1

我連接了JLS的相關部分。 '「HelloWorld」+ getstr()'不是**'字符串'(儘管它包含* 1:「Hello World」)。每次執行該行時都會生成一個新的String對象,並且該對象正常地被垃圾收集。 – 2010-06-02 10:47:28

+0

@JoachimSauer「HelloWorld」+ getstr()的情況1.當類加載時,仍然會創建「HelloWorld」? 2.我們是否需要使用如果我們不想停止垃圾收集的字符串,新的String(「HelloWorld」)會有幫助嗎? – Jaskey 2014-08-21 06:24:27