0
0

Javaで文字列が一致しているか確認する時はequalsを使う

Posted at

はじめに

もうタイトルだけで言いたい事は言ってしまった感があります。
私は業務でほとんどJavaしか使ってこなかったので当然のことだと思っていましたが、他の言語を勉強していく内に以外とequalsを使わないことが分かってきました。
Javaの子ども(だと勝手に思っている)Kotlinですら==で比較できる。

Kotlinでもequalsは使えます。

ということでこの件を浅く掘り下げます。

Stringはプリミティブ型ではない

Stringは1文字目が大文字である事からもわかるようにクラスとなります。
intbooleanといったプリミティブ型ではありません。
ではなぜ以下のような宣言ができるのか。

String text = "abc";
int num = 123;

これはStringだけの特殊な仕様により、コンパイラが自動的にStringオブジェクトを生成しているためです。
つまり、String text = "abc";の宣言は以下と 概念的には 同等になります。

String text = new String("abc");

文字列の比較で==を使うとどうなるか

クラスは参照型なので==を使うと同じ参照を見ているかを返します。
しかし下記のコードを実行すると想定と少し異なる結果になります。

String text1 = "abc";
String text2 = "abc";

System.out.println(text1 == text2); // true
System.out.println(text1.equals(text2)); // true

==で比較した方もtrueが返ってきました。
これは同じ文字列の値をもつStringオブジェクトが再利用される文字列インターンという特性のためです。
text1text2は文言が同じため、Stringオブジェクトが再利用され同じ場所を参照します。
そのため==で比較してもtrueとなるわけです。

ちなみに、Stringクラスのintern()というメソッドが文字列インターンと関連しているよです。

以下のように後から文字列の操作を行うと==では比較できなくなります。
Stringクラスは不変(イミュータブル)であるため、サンプルのように文字列の結合を行うと、新しいオブジェクトが生成されて、その内容がtext1text2に設定されるためです。

String text1 = "abc";
String text2 = "abc";
text1 += "def";
text2 += "def";

System.out.println(text1 == text2); // false
System.out.println(text1.equals(text2)); // true

まとめ

Java以外の言語を触った後にJavaを使うと、文字列が一致しているかで==を使ってしまう人がいるかもしません。
開発環境で正しい設定をしていればそのような場合に警告が表示されると思いますが、Javaで文字列を比較するときはequalsを使うという事を頭の片隅にでも覚えておいてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0