JavaでString文字列を==で比較してはイケナイと言われる理由
こんにちは!今日は少々マニアックな話になります。
Javaで文字列を比較するとき、==で比較してはイケナイというのは良く聞く話ですね。
本当かどうか、ちょっと試してみましょう。
String型の変数を2つ用意し、同じ文字列を格納して比較する
String str1 = "Hello World"; String str2 = "Hello World"; System.out.println(str1 == str2);
結果:true
となります。
あれ?大丈夫じゃん????
では、以下のケースを試してみましょう。
String型の変数を2つ用意し、加工して同じ文字列の状態にしてから比較する
String str1 = "Hello"; String str2 = "Hello World"; str1 = str1 + "World"; System.out.println(str1 == str2);
結果:false
となります。 結果的に両方共"Hello World"という文字列を格納していますが、falseです。
なぜなのか
==は、基本的に「同じ文字列であるかどうか」を判定します。
ですので、実は下記のように文字列が加工されない場合はあまり問題無いです。
String str1 = "Hello World"; String str2 = "Hello World"; System.out.println(str1 == str2);
問題になるのが、文字列に加工が入る場合です。
String str2 = "Hello"; str2 = str2 + "World";
この時、実は内部ではコレが起こっています。
String str2 = new String(str2 + "World");
つまり、全くの新しいオブジェクトを生成しています。
あとは、よくある動きですね。
String str1 = "Hello World"; String str2 = new String("Hello World"); System.out.println(str1 == str2);
結果:false
となります。
ちなみに、このケースでも
System.out.println(str1.equals(str2));
と、equalsメソッドを使ってやればシッカリと内部文字列の比較ができます。
まとめ
・Stringにおける==は、文字列の比較を行うようになっているため、文字列に加工が入らない限りは問題は起こりにくい
・ただ、明示的にnew String()が行われた場合の==はオブジェクトの比較を行う
・文字列の加工は、裏でnew String()を行う
・結論として、何があるかわからないので、基本的にequals()メソッドを使えばとりあえず安全!