2013-04-03 7 views
7

たStringBufferと文字列プール

StringBuffer str2 = new StringBuffer(" I don't"); 
    StringBuffer str3 = str2.append(" get it."); 
    if (str2 == str3) 
    { 
     System.out.println("Equal"); 
    } 

私の講師は言う、両方str2str3が同じオブジェクト と文字列を参照します。この場合には、それは意志「私はそれを得ることはありません」 "String pool"に挿入されます。

str2str3は同じオブジェクトを参照するようになると思いますが、なぜ文字列「私はそれを取得できませんか」 str3割り当てが発生したときに文字列プールに入りますか?例えば

、私がしなければ:

String s = "abcd"; 

その後、私はそのこと既にある場合は、ここで文字列「ABCD」は「文字列プール」に挿入されることを知っています。

私は説明をしたいです。

+1

@assylias:はい、それは意志、以来 'アペンド()' 'を返しますthis'。 –

+0

OPは、2つのオブジェクトが等しい理由を明確にしています。問題はなぜ文字列 "私はそれを取得しません"です。文字列プールに格納されます。 –

+2

あなたのインストラクターは間違っているかもしれませんが、StringBuffersの値が* interned *であることを意味する "String pool"に挿入されていれば、それは***間違いです。 – Perception

答えて

5

「私はそれを取得できません」という文字列はなぜですか。文字列プールに入る。

"I don't get it."文字列がインターンプールに入らない。次のようにそれを確認するために

一つの方法は次のとおりです。

StringBuffer str2 = new StringBuffer(" I don't"); 
StringBuffer str3 = str2.append(" get it."); 
String str = new String(str3.toString()); 
if (str == str.intern()) { 
    System.out.println("It was not interned before"); // <<== This is printed 
} else { 
    System.out.println("It was interned before"); 
} 

Stringのコンテンツが抑留されている場合は、intern()の呼び出しは異なる( 『正規』)オブジェクトを返します。ご覧のように、上記のオブジェクトは同じオブジェクトを返します。つまり、intern()と呼ばれるオブジェクトが「標準」オブジェクトになりました(つまり、中止されています)。一方

あなたがappendを削除した場合、あなたは異なる結果を取得したい:

StringBuffer str2 = new StringBuffer(" I don't"); 
StringBuffer str3 = str2; 
String str = new String(str3.toString()); 
if (str == str.intern()) { 
    System.out.println("It was not interned before"); // <<== This is printed 
} else { 
    System.out.println("It was interned before"); 
} 

str3内の文字列が" I don't"です。そのコピーは、str2の作成に使用された文字列定数と同じであるため、すでに中止されています。

あなた自身の違いを確認するには、the firstthe secondのプログラムを並べて実行できます。

str2 == str3trueの理由は、文字列プール(スラングワードは"string interning")とは関係ありません。 StringBuffer.appendはが呼び出されたオブジェクト、つまりstr2を返しますので、2つは等しいです。 2つ目のオブジェクトはありません。StringBufferと2つの参照があります。そのStringBufferの内容は、" I don't"" get it."の文字列の連結です。

+1

Ok、それはinterningという文字列とは関係ありませんが、文字列「私はそれを得ません」がそこに入るのは本当ですか? – Rouki

+2

いいえ、 "I do not get"という文字列は使用できません。 StringBufferのtoString()実装を読んで、それを確認します。 –

+0

@JBNizet誰かが「私はそれを手に入れません」というインターンについて話しています。もちろんそうではありません! – dasblinkenlight

0

さんのものではなく、StringBuffer個のオブジェクトを比較しています。 StringBuffer.append(String)の実装を見ると、return this;で終わるので、str2str3は同じオブジェクトです。

public synchronized StringBuffer append(String str) { 
super.append(str); 
    return this; 
} 

編集:あなたのコード内の2つの文字列リテラルが抑留されていますが、組み合わせた文字列(「文字列プール」で)抑留されることはありません「私はそれが得ることはありません」。これはStringBufferコード検査することにより明らかである(内部char[]配列の組合せを表す。)

乾杯、

+0

ありがとうございますが、私が言及したように、私は同じオブジェクトを参照する理由を得ると思います。文字列が "String pool"に挿入される理由を教えてください。 – Rouki

+1

文字列リテラル "I do not"と "get it"はインターンされ、2つの組み合わせはできません!内部的に 'StringBuffer'はchar配列を使用し、必要に応じて' new String(...) 'を作成しますが、これはインターンを必要としません。 –

0

StringBuffer#append(StringBuffer sb)

この配列に指定されたStringBufferを追加します。 のStringBuffer引数が のStringBufferの内容に順番に追加され、このStringBufferの長さが 引数の長さだけ増加します。 sbがnullの場合、このStringBufferに4文字 "null" が追加されます。

古い文字シーケンスの長さをnとし、appendメソッドを実行する直前にStringBufferに が含まれているものを指定します。次に、 新しい文字シーケンスのインデックスkの文字は、kが nより小さい場合、古い文字シーケンスのインデックスkの 文字に等しい。それ以外の場合は、引数sbの のインデックスk-nの文字に等しくなります。

このメソッドはこの(宛先)オブジェクトで同期しますが、 はソース(sb)で同期しません。

参照が同じであるため、あなたは真実になります。

0

混乱があるようです。 StringBufferは変更可能です。つまり、内容を変更できます。 StringBufferのメソッドappend()は、バッファ内の文字列にStringを追加し、そのインスタンスを返します。行よう:つまり、同じオブジェクトへのSTR3とstr2ポイントで

str2.append(" get it."); 
StringBuffer str3 = str2; 

StringBuffer str3 = str2.append(" get it."); 

は同じ実用的な結果を持つことになります。 Stringリテラルに「get it」を追加したためです。 "私はしない"には、このStringBufferは "私はそれを取得しません"が含まれます。

0

なぜ「私はそれを取得しません」という文字列があります。 str3の割り当てが発生したときに文字列プールに入りますか?

これはありません。あなたの講師はこの時点で間違っています。唯一の方法は、StringBufferがString.intern()を呼び出すか、または少なくとも指定するよう指定されていない場合です。

2

あなたが欠けているのは、string literalという概念です。

場合プールに追加の文字列:これはリテラルとして定義される

  • メソッドinternを呼び出します。

このプールにはまだ存在しません。

例では、文字列リテラルをタイプStringBufferのオブジェクトに入れます。そのオブジェクトから文字列を取得するには、toString()を呼び出す必要があります。結果を文字列プールに追加するには、その文字列にさらにintern()を呼び出す必要があります。

簡単なテストを実行できることを証明する。

String s1 = "This is a simple test"; 
String s2 = "This is a simple test"; 

System.out.println(s1 == s2); 

StringBuffer sb1 = new StringBuffer(s1); 
StringBuffer sb2 = new StringBuffer(s2); 

String result1 = sb1.toString(); 
String result2 = sb2.toString(); 

System.out.println(result1 == result2); 

String internedResult1 = result1.intern(); 
String internedResult2 = result2.intern(); 

System.out.println(internedResult1 == internedResult2); 

コード出力は次のようになります。



+0

いい例!私はここが見やすいと思う –

関連する問題