2013-07-23 7 views
5

私は、JavaのクラスStringを理解しようとしていますが、私は以下のような状況を理解することに苦労しています。私はbool = y == x.intern();を使用する場合は、変数booltrueに等しくなります使用インターンは

String x = new String("Hey"); 
String y = "Hey"; 

は、次の例のスニペットを考えてみましょう。

私の質問は:

私はこのような宣言をするとき:

String b = "h"; 
String a = b.intern + "ey"; 
boolean x = a == "hey"; 

xの値がfalseだろうが、私が作るときa = (b + "ey").intern();xの値はなりますtrue 。第二の例では

なぜだろうではないx = true最初の例の宣言が似ていないからですか?はいの場合、違いは何ですか?

+0

次のリンクはあなたに役立ちます:https://weblogs.java.net/blog/2006/06/26/all-about-intern –

+1

'String + String'は新しいStringに評価されます。 *魔法のように拘束されています:同じ内容の既存の拘束されたStringを見つけることを試みません。現在、両方のString式がリテラルの場合、コンパイル時に式全体が*折り返し*される可能性があります。*結果*のみがコンパイルされた出力にあり、標準のインターナショナルルールの影響を受けますが、 '(" h "+" ey ")==" hey "'は真です。折りたたみが削除されると(つまり、変数を使用すると)、これはなくなります。 – user2246674

+0

@TariqAymanあなたの質問を編集して、書式を改善しようとしました。あなたの質問のポイントが失われたと思ったら、それを見直してください。 – acdcjunior

答えて

5

"ちょっと" 文字列リテラル:

String y = "Hey"; 

Javaは自動的にこのような文字列リテラル(JLS section 3.10.5)インターン:

をまた、文字列リテラルは常にクラス ストリングの同じインスタンスを指します。より一般的にまたは、定数式(15.28)の値である文字列 - - メソッドString.internを使用して、一意のインスタンスを共有するように 「インターン」されている文字列リテラルがあるためです。

あなたがx.intern()を呼び出すときに、あなたは"Hey"のインターンコピーを取得するので、彼らは同じオブジェクトと==リターンtrueです。

しかし、第二の例では、b.intern()は、実行時に評価されたメソッドの呼び出しで、Javaの連結演算子は(すでにインターン)"hey"文字列リテラルとは異なる目的である、(internされていない)新しいStringを返します、したがって==false(異なるオブジェクト)を返します。 JLS Section 15.18.1に変わり、文字列の連結で何が起こるかまでクリアするには

EDIT

文字列連結の結果はの連結であるStringオブジェクトへの参照です 2つのオペランドストリング。左オペランドの の文字は、新しく作成された文字列の右側の オペランドの文字に先行します。

式が コンパイル時定数式(15.28)でない限り、Stringオブジェクトが新しく作成されます(§12.5)。

しかし、b.intern() + "ey";コンパイル時の定数式ではないので、結果Stringオブジェクトが抑留されていない、と==はそれがインターン"hey"とは異なるオブジェクトだことを検出します。

+0

ありがとうございました。ありがとうございましたが、b = "h" + "ey"のような新しいStringを作成した場合、これは連結されたStringですが、オブジェクトが存在しないため "hey" ? –

+0

コンパイラは '+'を最適化し、結果を自動的にインターナショナルにします。 –

+1

@LeeMeadorこれは、 '' h "+" ey "'などのコンパイル時定数式には当てはまりますが、 'b.intern()+" ey "'などのメソッド呼び出しには関係ありません。 – rgettman

3

この1つは、文字列や店舗、それを作成します。

String a = b.intern() + "ey"; 

この1つは、文字列、インターン、それを作成し、インターンバージョン保存:

String a = (b + "ey").intern(); 

を同じコンテンツを持つすべてのインターンの文字列は==あります

すべての文字列リテラル(形で供給された文字列「ちょっと」)は、内部コンパイラによって抑留されています。

インターンが、1つ以上、後世のためにのみequal()なく==

ある同じ内容を持っていない文字列が...コンパイラは「ちょっと」が生じ+を最適化し、ちょうどそれとしてインターンをでしょう、あなたの最初の例では

String a = "h" + "ey"; 
+0

ありがとうございます。しかし、なぜ文字列b = "h" + "ey"と "hey"はb .intern()+ "ey"? –

+0

どちらも内部ではないので、 '=='ではありません。それらは 'equal()'になります。同じ内容。メモリ内の別の場所。 –

+1

@Lee Meador - 'intern()'は*メソッド* –

0

JavaはStringBuilderを使用してString Sを連結:

b.intern() + "ey"
new StringBuilder(b.intern()).append("ey").toString()に似たものになります。これにより、新しいStringが作成されるため、=="hey"にはなりません。

関連する問題