2013-04-13 7 views
5
 String s1 = new String("string"); 
     String s2 = new String("string"); 

     String s3 = "string"; 
     String s4 = "string"; 

     System.out.println(s1 == s2);  //FALSE 
     System.out.println(s2.equals(s1)); //TRUE 

     System.out.println(s3 == s4);  //TRUE 
     System.out.println(s3.equals(s4)); //TRUE 

s1s3の作成の違いは何ですか? 私に教えてください割り当て、新しいString差を作成

Stringでは、Stringオブジェクトのみを持っていますが、なぜこの2つを別々に扱うのですか? s1とs2は異なるメモリアドレスを持ち、s3とs4は同じメモリアドレスを持っています。 new演算子に基づいて動作する理由

+0

Java Stringで概念を明確にしたい場合は、KathySierra Scjp 6をお読みください。第6章ストリングは、ストリングについてのすばらしい説明を持っています。あなたがpdfをほしいと思うならば、nikhilagrawal60 @ gmail.comで私にur mailIDを与えてください。他の誰かが興味を持っていれば、私にもメールを送ることができます。 –

+0

ありがとうございました..... – sunleo

答えて

5

Javaソースコード内の文字列リテラルを表すオブジェクトが、String共有プールに追加されます(これらのオブジェクトを定義するクラスがロードされるとき)。これにより、たとえリテラルが複数のクラスに現れても、文字列リテラルのすべての「コピー」が実際には同じオブジェクトであることが保証されます。だからs3 == s4trueです。

逆に、newの文字列を使用すると、別個の新しいStringオブジェクトが作成されます。そのため、s1 == s2falseです。 (これはnewの基本的なプロパティです。正常に完了すると、新しいオブジェクトを作成して返すことが保証されます。)

ただし、どちらの場合でも、文字列は同じ文字になります。そのため、equalstrueを返します。


何が起こっているかを理解することが重要であるが、本当レッスンは、Java文字列を比較する正しい方法はequalsなく==を使用することであるということです。

==を使用してStringオブジェクトの等価性をテストできるようにする場合は、String.internメソッドを使用してStringオブジェクトを「インターン」することができます。しかし、これを一貫して行う必要があります...そしてインターンは様々な面で高価なプロセスなので、一般的には良い考えではありません。

+0

なぜインターンは高価なプロセスですか? – AmitG

+1

多くの要因があります。 1)メモリを使用するハッシュテーブルがあり、 'intern'を呼び出すとプローブ/更新されます。 2)各内部文字列は、弱参照を使用してハッシュテーブルに格納されなければなりません。これは余分なメモリ+ GCオーバーヘッドです。 3)拘束された文字列は、(一般に限定された) "permgen"空間に格納されます。 GC'ing permgenは通常、完全なGCを必要とします。 –

+0

すばらしい説明。どこかで、Java 1.7の文字列がヒープのPermGen領域に入っていないと読んでいますか?本当? – AmitG

2

JVMには自動最適化機能があります。新しいStringオブジェクトを作成し、同じ値を持つ別のStringオブジェクトが既に存在する場合を除き、JVMは自動的に新しいオブジェクトが不要であるとみなし、既に存在するオブジェクトStringオブジェクトへのポインタを割り当てます。

2番目のオプションを使用する場合、基本的に、これは何が起こるかです:

ステップ1

第一の目的は、何の問題も作成されません。

ステップ2

二オブジェクトが作成される前に、文字列のプールは、値がチェックされます。 その値が現在存在する場合は、新しいオブジェクトを作成する必要はありません。これは単にStringオブジェクトへの参照を返します。

ステップ3

代わりに新しいオブジェクトを割り当てられると、それは、単にこれは、メモリを節約することであるステップ1で作られたオブジェクトへの参照を与えています。

+1

なぜdownvote? – christopher

3

s1は、プールされたインスタンスの一部に属していない新しいStringオブジェクトです。 s3はプールからの文字列のインスタンスです。検索java文字列プールStringに関する関連するintern()の方法を見てください。

概念はJava固有のものではありません。 String interningは他の言語でもサポートされています。その関連するノートでは、頻繁に使用されるオブジェクトをプールすることは、flyweightパターンに従って行われ、文字列に限定されません。 Integer.valueOf()を見てください。整数には一定のプールがあります。

0

これは、new演算子がStringの新しいインスタンスの作成を強制するためで、2番目のケースではStringが不変クラスであるため、JVMはメモリを節約するために両方の変数に同じStringインスタンスを提供します。そのようなオブジェクトの1つが変わるので、2番目の変更も同様に起こります(変更不可、覚えていますか?)これは問題ありません。

関連する問題