2017-02-10 12 views
0

だから私は読んだこと、あなたが書く場合は、この:比較文字列が

String a="foo"; 
String b="foo"; 
System.out.println(a==b); 
最初の実装は、「探しているメモリプールをチェックするので、それは、「真」に印刷されます

foo "を見つけたら、新しいオブジェクトを作成してfooをメモリプールに入れて、他のすべての文字列が同じオブジェクトを指し示すようにします。

、あなたが書いた場合:あなたは、Bのための新しいオブジェクトの作成を強制するので、それは文句を言わないプールからそれを取るよう

String a="foo"; 
String b=new String("foo"); 
System.out.println(a==b); 

それは、「偽」に印刷されます。あなたがこれを書いた場合

、私の質問は:

String a=new String("foo"); 
String b="foo"; 
System.out.println(a==b); 

なぜそれはまだ「偽」印刷していますか?私は "a"は新しいオブジェクトを作成し、メモリプールを調べませんが、bはメモリプールを見て、オブジェクト "a"を作成してそれを指すはずです。私はここで何が欠けているのですか? ありがとうございます。

+0

aはmemoryPoolにないため、aとbはdif参照を指しています.... –

+0

'String a = new String(" foo ");' 2つのオブジェクトを作成します。最初に '' foo''を作成し、次に 'new String'を使ってもう一つ作成します。 – marstran

+0

これは簡単です。文字列用のStringプールとオブジェクト用のObjectプールがあります。文字プール内の文字列とオブジェクトプール内のStringオブジェクトを比較することはできません。==直接 – PSo

答えて

1

新しいオブジェクトを作成すると、そのオブジェクトはプールには存在しません。

bは、メモリプールを検索し、オブジェクト "a"が作成され、それを指していることがわかります。

それはプールにありますが、それはそう==はまだ偽である"foo"オブジェクトでないnew String("foo")オブジェクトを返します。

あなたは、このような

String a = "food".substring(0, 3).intern(); 
String b = "foo"; 
assert a == b; 
-1

列Aは文字列Bが行う、文字列プールに行かないよう.intern()でプールに文字列を置くことができます - ので、参照が異なっています。それがあなたが偽になる理由です。

+0

ここには3つの 'String a'宣言があります。あなたはどちらについて話していますか? – EJP

0

一般的に共通プールはヒープの一部ですが、newで作成されたオブジェクトは決してプールには入りません。作成中に使用されるリテラルがプールに移動するためです。リテラルを比較すると、あなたが言ったことは真実になります。リテラルとオブジェクトに対してではありません。

1

String a="foo";

- 文字列プールが1つを持っていない場合>、文字列プールを確認文字列プールに

String b="foo";

を新しいStringオブジェクトを作成 - >文字列プールが含まれている場合は、文字列プールをチェックそれは、そのStringオブジェクトへの参照を作成します。

String c=new String("foo");

これは、直接文字列プール外であるが、オブジェクトプール(メモリー)に新しいStringオブジェクトを作成します。

オブジェクトの視点では、2 Stringオブジェクトは同じです。したがって、それらを比較するために.equalsを使用すると、trueを返します。しかし、==を使用して比較する場合、同じオブジェクトを指していない参照を比較するので、falseを返します。詳細は

http://theopentutorials.com/tutorials/java/strings/string-literal-pool/

1

あなたはプールの仕組み誤解:あなたは

String a = "foo"; 

を行うときに、あなたが最初にそれを作成するためStringオブジェクト"foo"がプールにない終わるが、しかし理由文字列リテラル(二重引用符で囲まれた文字のシーケンス)に基づくオブジェクトです。 Javaはこのオブジェクトを定数プールに作成します。

あなたは

String a = new String("foo"); 

を書くときにプールから文字列オブジェクト"foo"がプールに置かれない新しいStringオブジェクトにコピーされます。