2012-11-19 20 views
8

可能性の重複:
String object creation using new and its comparison with intern method同じjava文字列が同じアドレスを使用するのはなぜですか?

私はより多くのそれらを理解するために文字列で遊んでいたと私は私が説明できない何かに気づいた:

String str1 = "whatever"; 
String str2 = str1; 
String str3 = "whatever"; 
System.out.println(str1==str2); //prints true...that's normal, they point to the same object 
System.out.println(str1==str3); //gives true..how's that possible ? 

どのようにされました最後の行は本当ですか?これは、str1とstr3の両方がメモリ内の同じアドレスを持つことを意味します。

これはコンパイルの最適化で、文字列リテラルが同じであること(「whatever」)が検出され、str1とstr3が同じオブジェクトに割り当てられていることを検出できるかどうかです。あるいは、私は文字列の基本的な仕組みに何かを見逃していますか?

+1

javacコンパイラは、このような単純なケースを検出して、文字列のスペースを1回だけ割り当てて再利用することができます。実行時には別の話です。 – nhahtdh

+0

http://stackoverflow.com/a/513839/1273830> "これらのリテラルはコンパイラによってインターンされているため、同じオブジェクトを参照しているためです!" – Prasanth

答えて

5

http://www.xyzws.com/Javafaq/what-is-string-literal-pool/3

ポストが言うように:

文字列の割り当てを、すべてのオブジェクトの割り当てと同様に、時間とメモリの両方に高価な証明しています。 JVMは、文字列リテラルをインスタンス化しながらパフォーマンスを向上させ、メモリオーバーヘッドを減らすためにいくつかのトリッキーを行います。 JVMで作成されたStringオブジェクトの数を減らすために、Stringクラスは文字列のプールを保持します。コードが文字列リテラルを作成するたびに、JVMは文字列リテラルプールを最初にチェックします。文字列がプール内にすでに存在する場合、プールされたインスタンスへの参照が返されます。文字列がプール内に存在しない場合、新しいStringオブジェクトがインスタンス化され、プール内に配置されます。

7

Javaには一意のinternedインスタンスのプールがあり、その文字列リテラルがこのプールに格納されているためです。これは、最初の "whatever"文字列リテラルが、3番目の "whatever"リテラルとまったく同じStringオブジェクトであることを意味します。文書として

は言う:

public String intern()

文字列オブジェクトの正準表現を返します。最初は空の文字列のプールは、文字列クラスを非公開にして維持されます。プールは既に等しい(オブジェクト) 方法によって決定されるように、この文字列オブジェクトに等しい 文字列が含まれている場合、インターンメソッドが呼び出され

は、その後、プールから文字列が返されます。そうでない場合は、 Stringオブジェクトがプールに追加され、このString オブジェクトへの参照が返されます。

したがって、s.equals(t)が真である場合に限り、s.intern()== t.intern() はtrueになります。

リテラル文字列と文字列定数定数は、すべて です。文字列リテラルは、Java言語仕様

戻り値の3.10.5で定義されています。この文字列と同じ内容を持つ文字列が、ユニークな文字列のプールからであることが保証 です。


+0

これについてのメモを追加するには、string1 == string2を使用しないでください。とにかく、指定された "text"のインスタンスが2つ存在しないことが保証されていないためです。常にstring1.equals(string2)を使用するか、コンテキスト内の比較に適したものを使用してください。 – philnate

+0

@philnate:exactly ... :) – Parth

1

javacコンパイラは、指定されたクラスファイル内で同じ文字列リテラルを結合します。しかし、実行時に、文字列リテラルは、これは、同じオブジェクトを使用するのと同じJVMで異なるアプリケーション(で別のクラスでも、文字列の意味String.intern()と同じアプローチを使用して結合さ

2

あなたがない場合:。

String str1 = new String("BlaBla"); //In the heap! 
String str2 = new String("BlaBla"); //In the heap! 

、あなたが明示的にnew演算子(コンストラクタ)を介してStringオブジェクトを作成している。 この場合、あなたは異なる保管場所を指す各オブジェクトを持っています。

しかし、あなたがしなければ:

String str1 = "BlaBla";   
String str2 = "BlaBla"; 

を、あなたは、暗黙的な工事をしました。 2つの文字列リテラルが同じ値を持つ場合、同じ記憶域を共有します。これは、Javaが同じ文字列の記憶域を節約するためです。 (同じ値を持つ文字列)

関連する問題