2011-08-08 64 views
0

一件事,我一直在想,如果我有這樣的方法:在java中的字符串和內存分配?

String replaceStuff (String plainText) { 
     return plainText.replaceAll("&", "&"); 
} 

將它創建新的String對象都爲得到由GC破壞了「&」和「&」和時間然後再次通過下一個電話重新創建? 例如 將它在理論上是更好的做這樣的事情

final String A ="&"; 
final String AMP ="&"; 

    String replaceStuff (String plainText) { 
      return plainText.replaceAll(A, AMP); 
    } 

我想這大概是比現實生活中的問題更多的理論問題,我只是好奇,內存管理是如何在這方面的處理。

回答

4

編號字符串文字是interned。即使你從其他地方使用相同的文字(或其他常數),你還是會指向同一個目標:

Object x = "hello"; 
Object y = "he" + "llo"; 

System.out.println(x == y); // Guaranteed to print true. 

編輯:JLS保證這部分3.10.5

字符串文字 - 或者更一般地說,是常量表達式(§15.28)值的字符串 - 被「實施」,以便使用方法String.intern共享唯一實例。

第15.28節顯示+操作符被包含在一個操作中,該操作符可以從兩個其他常量中產生一個新的常量。

+0

它保證'Object y =「hello」',但是''he「+」llo「的編譯器優化是否也有保證? (我問,沒有挑戰性:-)) –

+0

這是一個很好的例子! – Vlad

+1

@肖恩:它也有保證。它在JLS中的§3.10.5的[本部分](http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#19369)中:「字符串文字 - 或者更一般地,作爲常量表達式的值的字符串(§15.28) - 被「interned」[...]「 –

3

不,他們是文字,因此會自動實現常量池。

只有這樣,您需要創建新的字符串每次都將做到:

String replaceStuff (String plainText) { 
    return plainText.replaceAll(new String("&"), new String("&")); 
} 
1

字符串的處理比GC正常對象略有不同。 例如,如果

String a =「aaa」; String a1 =「aaa」;

現在,a和a1都將指向內存中相同的字符串值,直到任何值發生更改。因此內存中只有一個對象。另外,如果我們將'a'和'a1'更改爲指向任何其他字符串,仍然將值「aaa」留在字符串池中,如果需要,JVM將稍後使用它。該字符串不是GC'd

+0

其實他們是**不是由GC處理不同,但在施工期間。 –

+0

值得注意的是這是編譯時字符串*常量*。以其他方式創建的字符串不會自動實現。 –