はじめに
Javaを勉強していると、文字列やオブジェクトの比較で必ず登場する「==
」と「equals()
」。
なんとなく使っていて、「結局どっちを使えばいいの?」と迷った経験、ありませんか?
この記事では、「==」と「equals()」の本当の違いを、初心者でもわかりやすく、図やコード例を交えて徹底解説します。
1. 結論:==は「参照の比較」、equals()は「内容の比較」
比較方法 | 意味 | 主な使いどころ |
---|---|---|
== | 同じものかどうか(参照比較) | インスタンスが完全に同一か確認したいとき |
equals() | 中身が同じか(値の比較) | 値や状態が同じか確認したいとき |
2. 例でサクッと確認してみよう
1 2 3 4 5 6 7 8 |
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() の違い
1 2 3 4 5 6 7 8 9 |
== 比較(参照) ┌───────────┐ ┌───────────┐ │ s1 │ │ s3 │ │ → "Java" │ │ → "Java" │ (中身は同じでも別物) └───────────┘ └───────────┘ equals() 比較(内容) s1.equals(s3) → "Java" と "Java" は同じ内容 → true |
4. Stringの場合の注意点:文字列プール
Javaの文字列は**文字列プール(String Pool)**という仕組みで管理されます。
同じリテラル(例:"Java"
)は、同じメモリ領域を共有します。
1 2 3 4 5 |
String a = "Java"; String b = "Java"; System.out.println(a == b); // true |
でも、new
で作ると新しいインスタンスになります。
1 2 3 4 5 |
String c = new String("Java"); System.out.println(a == c); // false System.out.println(a.equals(c)); // true |
5. プリミティブ型と参照型で「==」の動作が違う!
型の種類 | == の比較対象 |
---|---|
プリミティブ型 | 値そのもの |
参照型 | メモリアドレス(参照先) |
1 2 3 4 5 6 7 8 9 |
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()
が定義されています。
1 2 3 4 |
public boolean equals(Object obj) { return (this == obj); } |
つまり、デフォルトでは ==
と同じ挙動です。
ですが、String
や Integer
などは、equals()
を内容比較用にオーバーライドしています。
7. equals() を自作クラスで正しく使うには?
オリジナルのクラスで「中身が同じかどうか」を比較するには、equals()
をオーバーライドする必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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()
もセットでオーバーライドしましょう!
1 2 3 4 5 |
@Override public int hashCode() { return name.hashCode(); } |
これは、HashMap
や HashSet
のようなコレクションで正しく動作させるために必須です。
9. まとめ:== と equals() の違い早見表
比較方法 | 比較する内容 | 主な用途 |
---|---|---|
== | 参照(オブジェクトの場所) | インスタンスが同じか確認したいとき |
equals() | 内容(オブジェクトの中身) | 値が同じかどうか確認したいとき |
10. よくあるミスとその回避法
❌ == を使って文字列を比較
1 2 |
if (str == "Hello") // 危険 |
これは参照比較なので、思ったように動作しないことが多いです。
✅ equals() を使おう
1 2 |
if ("Hello".equals(str)) // 安全! |
このように定数を先に書くとnullも回避できて、安全です。
📘 Javaをもっと深く理解したい方へ
このような「Javaの動作の本質」をしっかり理解したいなら、「絶対にJavaプログラマーになりたい人へ。」という書籍がおすすめです。
🎓 わからないことは「サイゼントアカデミー」で解決!
- 現役エンジニアが丁寧に教えてくれる
- コードレビューが受けられる
- Javaに特化した転職サポートも充実
おわりに
「==」と「equals()」の違いは、Javaの理解度を測るひとつの分かれ道です。
この違いをしっかり理解しておくことで、バグの少ない、安全で読みやすいコードが書けるようになります!
コメント