上の答えっぽいもの
えーっと、まずStringを==で比べるの?という突っ込みを2,3いただきました。
普通やらんでしょ、というのは承知しておりますです、ハイ。
そもそもの始まりは、JAVA初心者に教えるときに(私もアレなんですが・・・)
「文字列比較をしたい時は==じゃダメなんですよー」
と教えるつもりだったんですけど、私もアレなもんで、ホントにだめだよねぇ?という確認をしようとしたのが始まりだったんです。
んでもって、先生をつかまえて聞いてみたんですけど、こんなイメージらしいです
newで宣言したStringオブジェクトは、プログラムで扱うメモリー領域に作成される。
a = "abc"; などで暗黙的に作成されたオブジェクトのデータは「リテラルプール」なるメモリー空間の方に格納され、ここにあるリテラルデータはプログラムから共用で使用される。
ってな感じらしい。
そうすると
String a = "abc"; //リテラルプールに"abc"を格納 String b = "abc"; //リテラルプールに同じ値があるのでaと共用
これだとa == bがtrueになる。
うん、上のソースの動きだ。
んでもって、
String a = new String("abc"); //プログラムのメモリー領域に新規オブジェクト作成 String b = new String("abc"); //上記オブジェクトは共用されないので、別のオブジェクトを新規作成
これだと、a == bがfalseになる。
ふむ。コレもそうなるねぇ。
んじゃ
String a = "abc"; String b = "abc"; a = a + "test"; b = b + "test";
これがfalseなのはなんでだ?
あー、一瞬わかった気になったけどやっぱりわかんねぇ。
でも先生からすごいこと教わったんで、もう解決です。
「.equals(obj)でいいじゃん」
うん、その通りです!
つーことで、コレばっかり調べてもいられないのでいったんお終い。
あ、でも「こういう事だよ」とか教えてくれるのは全然嬉しいのでJAVAに詳しいかたコメントとかよろしくです。
追記:
あくまで仮定なんですけどね。
Stringクラスのドキュメントを眺めてたらこんな一文が
Java 言語は、文字列連結演算子 ( + )、およびその他のオブジェクトから文字列への変換に対する特別なサポートを提供します。文字列連結は StringBuffer クラスとその append メソッドを使って実装されています。
ふむ、ここらへんが関係あるんですかね。関係ない?そうですか。
でも変数とリテラルを連結した場合には、その結果はリテラルプールには格納されないっぽいとか仮定してみる。
String a = "abc"+"test";
だと"abctest"というリテラルを作成し、これをリテラルプールに格納。
String a = "abc"; a = a + "test";
だと、aという変数を使用して新たなオブジェクトを作成するから、これはnewしたのと同じ扱い(リテラルプールではない)って事ですかね。
もしかしたらリテラルプールなのかも知れないけど、"abctest"とは別のデータ扱いと。
そうすると
String a = "abc"; //リテラルプールに"abc" a = a+"test"; //プログラム領域に"abctest"を格納するStringオブジェクトを作成 String b = "abctest"; //リテラルプールに"abctest"を格納
これで、a==bがfalseって事になる。これなら納得。
先生、こういう仮定はどうですか?