2011-08-08 5 views
0

一つのこと、私はこのような方法がある場合:javaでの文字列とメモリの割り当ては?私はいつも疑問に思って

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

を、それは新しい文字列を作成するには、GCによって破壊されます「&」と「&」のためにすべての時間をオブジェクトと次の呼び出しで再び作成されましたか? など。 は、それは理論的には私は、これはおそらく、実際の生活の問題よりも理論的な質問だと思います。この

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

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

のような何かをする方が良いだろう、私はメモリ管理が、この局面ではどのように扱われるかだけ興味があります。

答えて

4

いいえ。文字列リテラルは使用できません。あなたが他の場所から同じリテラル(または他の定数)を使用する場合でも、同じオブジェクトを参照します:

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

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

EDIT:JLS保証このセクションでは3.10.5

文字列定数式の値である文字列(15.28節)は、String.internというメソッドを使用して一意のインスタンスを共有するように「中止」されています。

15.28節では、他の2つの定数から新しい定数を生成できる演算子として+演算子が含まれています。

+0

'Object y =" hello "'は保証されていますが、 "he" + "llo" 'のコンパイラ最適化も保証されていますか? (私は、挑戦しないで、質問しています:-)) –

+0

それは素晴らしい例です! – Vlad

+1

@Sean:それも保証されています。 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"; 文字列a1 = "aaa";

ここで、aとa1の両方が、値が変更されるまでメモリ内の同じ文字列値を指します。したがって、メモリには1つのオブジェクトしか存在しません。

また、他の文字列を指すように 'a'と 'a1'を変更すると、値「aaa」が文字列プールに残り、必要に応じて後でJVMで使用されます。文字列はGC'dではありません

+0

実際には、GCでは処理されませんが、構築中は処理されません。 –

+0

これはコンパイル時の文字列*定数*であることに注意する価値があります。他の方法で作成された文字列は、自動的に格納されません。 –

関連する問題