Javaの==とequals()の本当の違いとは?初心者にもわかる図解付きで徹底解説

Java

はじめに

Javaを勉強していると、文字列やオブジェクトの比較で必ず登場する「==」と「equals()」。
なんとなく使っていて、「結局どっちを使えばいいの?」と迷った経験、ありませんか?

この記事では、「==」と「equals()」の本当の違いを、初心者でもわかりやすく、図やコード例を交えて徹底解説します。


1. 結論:==は「参照の比較」、equals()は「内容の比較」

比較方法意味主な使いどころ
==同じものかどうか(参照比較)インスタンスが完全に同一か確認したいとき
equals()中身が同じか(値の比較)値や状態が同じか確認したいとき

2. 例でサクッと確認してみよう

String s1 = "Java";
String s2 = "Java";
String s3 = new String("Java");

System.out.println(s1 == s2);      // true
System.out.println(s1 == s3);      // false
System.out.println(s1.equals(s3)); // true
  • s1 == s2同じ文字列リテラルなので true
  • s1 == s3別のオブジェクトなので false
  • s1.equals(s3)内容が同じなので true

3. 図解:== と equals() の違い

== 比較(参照)
┌───────────┐    ┌───────────┐
│   s1                 │    │   s3      │
│  → "Java"           │    │  → "Java" │  (中身は同じでも別物)
└───────────┘    └───────────┘

equals() 比較(内容)
s1.equals(s3) → "Java" と "Java" は同じ内容 → true

4. Stringの場合の注意点:文字列プール

Javaの文字列は**文字列プール(String Pool)**という仕組みで管理されます。
同じリテラル(例:"Java")は、同じメモリ領域を共有します。

String a = "Java";
String b = "Java";

System.out.println(a == b); // true

でも、newで作ると新しいインスタンスになります。

String c = new String("Java");

System.out.println(a == c); // false
System.out.println(a.equals(c)); // true

5. プリミティブ型と参照型で「==」の動作が違う!

型の種類== の比較対象
プリミティブ型値そのもの
参照型メモリアドレス(参照先)
int x = 10;
int y = 10;
System.out.println(x == y); // true(値が同じ)

Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println(a == b); // false(別のオブジェクト)
System.out.println(a.equals(b)); // true(値は同じ)

6. equals()の中身をのぞいてみよう

全てのJavaオブジェクトは、Object クラスを継承しています。
その中に、equals() が定義されています。

public boolean equals(Object obj) {
    return (this == obj);
}

つまり、デフォルトでは == と同じ挙動です。
ですが、StringInteger などは、equals()内容比較用にオーバーライドしています。


7. equals() を自作クラスで正しく使うには?

オリジナルのクラスで「中身が同じかどうか」を比較するには、equals()オーバーライドする必要があります。

public class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person p = (Person) obj;
        return this.name.equals(p.name);
    }
}

8. equals() をオーバーライドするときの注意点

equals() をオーバーライドしたら、hashCode() もセットでオーバーライドしましょう!

@Override
public int hashCode() {
    return name.hashCode();
}

これは、HashMapHashSet のようなコレクションで正しく動作させるために必須です。


9. まとめ:== と equals() の違い早見表

比較方法比較する内容主な用途
==参照(オブジェクトの場所)インスタンスが同じか確認したいとき
equals()内容(オブジェクトの中身)値が同じかどうか確認したいとき

10. よくあるミスとその回避法

❌ == を使って文字列を比較

if (str == "Hello") // 危険

これは参照比較なので、思ったように動作しないことが多いです。

✅ equals() を使おう

if ("Hello".equals(str)) // 安全!

このように定数を先に書くとnullも回避できて、安全です。


📘 Javaをもっと深く理解したい方へ

このような「Javaの動作の本質」をしっかり理解したいなら、「絶対にJavaプログラマーになりたい人へ。」という書籍がおすすめです。

👉 絶対にJavaプログラマーになりたい人へ。


🎓 わからないことは「サイゼントアカデミー」で解決!

  • 現役エンジニアが丁寧に教えてくれる
  • コードレビューが受けられる
  • Javaに特化した転職サポートも充実

👉 サイゼントアカデミー


おわりに

「==」と「equals()」の違いは、Javaの理解度を測るひとつの分かれ道です。

この違いをしっかり理解しておくことで、バグの少ない、安全で読みやすいコードが書けるようになります!

コメント

タイトルとURLをコピーしました