hyukiさんから頂いた問題

hyuki 『以下もどうぞ。
String s = "abc";
System.out.println(s == s.replace('a', 'a'));
System.out.println(s == new String(s));
System.out.println(s == new String("abc").intern());』 (2005/12/29 22:08)

結果


true
false
true
s == new String(s) が false を返すのは同一のオブジェクトでは無いから。
System.out.println(s.equals(new String(s)));
なら同じ文字列なので true を返す。


s == s.replace('a', 'a')
replaceメソッドの説明を読むと一見 false が返ってきそうな気がする。

public String replace(char oldChar,char newChar)
この文字列内にあるすべての oldChar を newChar に置換した結果生成される、新しい文字列を返します。

新しい文字列であって新しいオブジェクトではないので true が返る。


s == new String("abc").intern()
さて、問題はこれですね。新しく String オブジェクト作ってるから false が返ってきそうなのに true が返ってる。

public String intern()
文字列オブジェクトの正準表現を返します。
文字列のプールは、初期状態では空で、クラス String によってプライベートに保持されます。

intern メソッドが呼び出されたときに、equals(Object) メソッドによってこの String オブジェクトに等しいと判定される文字列がプールにすでにあった場合は、プール内の該当する文字列が返されます。そうでない場合は、この String オブジェクトがプールに追加され、この String オブジェクトへの参照が返されます。

このため、任意の 2 つの文字列 s と t においては、s.equals(t) が true の場合にのみ、s.intern() == t.intern() は true になります。

新しい String オブジェクトを生成する。
String regex = new String("abc");
s.equals(regex) は true なので s.intern() == regex.intern() も true になる。


hyukiさん、ありがとうございます。