- PR -

String インスタンスの比較について

1
投稿者投稿内容
hanny
会議室デビュー日: 2003/07/31
投稿数: 13
投稿日時: 2006-05-15 10:41
String クラスのインスタンスを比較した際の振る舞いに関する質問です。

String strA = "hello";
String strB = "hello";

とした時に、

strA == strB は true を返します。(必ずかどうかは分かりませんが、少なくとも私の試した環境ではそうなりました。j2sdk1.4.2_10)

このことに関する説明として、
「既に strA 生成時に "hello" のインスタンスが存在しており、strB も同様のインスタンスを参照しているために true を返す。」
と理解していました。

しかし、以下のような場合には
String strC = new String("good day");
String strD = "good day";
String strE = "good day";

strC == strD は false
strD == strE は true

となります。
これは、最初の説明にしたがって考えると、strC を生成時のインスタンスを strD および、strE も参照しこれらの比較は両方とも true を返してもよさそうに思えますが、実際には、そうはなりませんでした。

これは、何故でしょうか?
また、 strC と strD は(1.4.2_10においては)必ず、異なるインスタンスを参照するのでしょうか?

以上、宜しくお願いします。
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2006-05-15 11:01
newした時点で、コピーが作られるからでしょう。
hanny
会議室デビュー日: 2003/07/31
投稿数: 13
投稿日時: 2006-05-15 11:08
mio さん回答ありがとうございます。

コピーとは何のコピーが作られるのでしょうか?
strC を new した段階では、"good day" 文字列をもつインスタンスは他に存在していないのですが、どのようにコピーを生成しているのでしょうか?
strD と strE が先に生成されて、その後に strC が new されるということでしょうか?

ゆう
常連さん
会議室デビュー日: 2003/06/27
投稿数: 45
投稿日時: 2006-05-15 11:11
 strD == strEがtrueになるのは、String型のリテラル文字列を指定した際
にString.intern()メソッドが実行され、internメソッド専用の文字列表から
リテラル文字列を取得しているためらしいです。

 newから明示的にインスタンスを作成した場合、internメソッドが実行され
ないため、strC != strDとなるのではないでしょうか。

 以下のようにすると、intern専用文字列表に"good day"が登録されるため、
すべての==比較がtrueになります。

コード:

String strC = new String("good day").intern();
String strD = "good day";
String strE = "good day";



[ メッセージ編集済み 編集者: 悠 編集日時 2006-05-15 11:18 ]
hanny
会議室デビュー日: 2003/07/31
投稿数: 13
投稿日時: 2006-05-15 11:17
悠さん 回答ありがとうございます。

ご教授頂いた内容と、APIリファレンスを参照し、理解することが出来ました。
ありがとうございました。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-05-15 11:17
まず、話の腰を折るようですが、String クラスは Java 言語自体に埋め込みの特別なクラスであるため、ダブルクォーテーションで囲まれた文字列のインスタンスが実際どうなるかを気にすることは、たしかに Java の細かな言語仕様と String クラスの細かな仕様の理解にはなります。しかし、他の一般的なクラスの取り扱いの理解には役立ちません。
私としては、ダブルクォーテーションで囲まれた文字列のインスタンスは不定である、という前提でコードを書くだけにしたほうが良いと思います。

上記を踏まえたうえで、では、本来の String クラスの振るまいについてですが、...難しくてパス。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
hanny
会議室デビュー日: 2003/07/31
投稿数: 13
投稿日時: 2006-05-15 11:31
unibon さん。
ありがとうございます。
私も、 String クラスが特別なクラスであることは承知しております。
String var = "string" でインスタンスが出来てしまうということ自体、一般的な classの使用方法とはかけ離れていますし。

今回疑問を持ったのは、
「既に strA 生成時に "hello" のインスタンスが存在しており、strB も同様のインスタンスを参照しているために true を返す。」
という今までの自分の理解に疑問が有った為です。

お恥ずかしい話ですが、質問をした経緯は開発メンバーに
「 String var = new ("hoge"); 等としているコードは String var = "hoge"; のように直しましょう」
と指示していたのに自分自身の理解では
「strC == strD は false」の「何故?」に答えられないと感じたためです。

ご指摘頂いた様に、実際のコーディングの中には 文字列のインスタンス同士を比較する ようなことはしないように心がけて行きたいと思います。

ありがとうございました。

1

スキルアップ/キャリアアップ(JOB@IT)