はじめに

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 → 違うオブジェクトなので false
  • str1.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() をオーバーライドする。