Table of Contents
はじめに
Javaでif文を書くときに、「==
と equals()
は何が違うの?」 という疑問が出るかと思います。
「比べるならどちらでもいいんじゃないの?」と思いがちですが、実は使い方を間違えるとバグの原因になります。
この記事では、==
と equals()
の違いをわかりやすく解説し、初心者がつまずきやすいポイントも紹介します。
基本の違い
簡単に言うと、以下が違いとなります。
==
:同じ箱かどうかequals()
:箱の中身が同じかどうか
具体例
1. 基本データ型(プリミティブ型)
int a = 10;
int b = 10;
System.out.println(a == b); // true
プリミティブ型では ==
で値を比較できます。equals()
は使えません。
2. 参照型(オブジェクト)
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // false(参照が違う)
System.out.println(str1.equals(str2)); // true(内容が同じ)
ここが重要ポイントです。
str1 == str2
→ 違うオブジェクトなので falsestr1.equals(str2)
→ 中身の文字列が同じなので true
注意が必要な場面
1.Stringの==
とequals
String s1 = "apple";
String s2 = "apple";
System.out.println(s1 == s2); // true(同じ文字列リテラルは同一参照になる)
System.out.println(s1.equals(s2)); // true
文字列リテラルは同じ場所を共有するので ==
でも true になりますが、new String()
を使うと別物になります。
つまり:
- 常に中身を比べたいなら
equals()
を使うのが安全。
2.nullとの比較
String text1 = null;
System.out.println("ABC".equals(text1)); // false
System.out.println(text1.equals("ABC")); // 比較できずエラー(Exception)が発生する
上記のように、「null」をequalsの左側において比較すると、エラーが発生します。
よって、2行目のように、確実にnullにならない方を左側において比較することでエラー発生を避けることができます。
equals() をオーバーライドする
自作クラスでは equals()
をオーバーライドしないと、デフォルトでは ==
と同じ動作になります。
例:
class Person {
String name;
Person(String name) { this.name = name; }
}
Person p1 = new Person("Bob");
Person p2 = new Person("Bob");
System.out.println(p1.equals(p2)); // false(オーバーライドしないと参照比較)
これを正しく比較するには以下となります。
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return Objects.equals(name, person.name);
}
まとめ
- プリミティブ型 →
==
で比較。 - オブジェクト型 → 中身を比較したいなら
equals()
を使う。 String
は特に混乱しやすいのでequals()
を使うのが安心。- nullの可能性がない方を
equals()
の左側に置いて比較する。 - 自作クラスは
equals()
をオーバーライドする。