JAVA

Javaのequalsと==徹底比較|正しい使い分けとバグ回避策

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


スポンサードリンク

1. 基本は「参照か値か」だけ

演算子 / メソッド 比較対象 何が評価されるか
== 任意の型(プリミティブ・オブジェクト) 参照そのもの(同一メモリ位置)
※プリミティブの場合は値そのまま
equals() オブジェクト クラスが実装した 内容(論理的な等価性)
Object.equals は参照比較しか行わないが、ほとんどのクラスでオーバーライドされている
  • 同一オブジェクトか知りたい==
  • 「見た目」や「意味的に等しいか」判定したいequals()

例)文字列リテラルはプールに格納されるため s1 == s2 が true になることがあるが、実装上は常に equals() を使うべきです。


2. String の比較で注意すべき落とし穴

2‑1. リテラル vs new String

  • リテラル同士は == が true になることがあるが、外部入力や new String() で生成した文字列は必ず別オブジェクトです。
  • 実務では常に equals()(または Objects.equals)を使うのが安全です。

2‑2. ユーザー入力・外部データ

input == "yes" はほぼ常に false になるため、文字列比較では == を使用しないでください。


3. ラッパークラス(オートボクシング)とキャッシュ

3‑1. キャッシュがある範囲

クラス JDK がキャッシュする範囲(valueOf / オートボクシング時)
Integer -128 ~ 127
Long -128 ~ 127
Short -128 ~ 127(※全てがキャッシュされるわけではなく、この範囲は保証)
Byte 全ての値(‑128 ~ 127)は必ずキャッシュ
Character \u0000 ~ \u007F(0〜127)

ポイントShort が「全体を」キャッシュするという情報は誤りです。JDK の仕様上、-128〜127 のみが保証されます。

3‑2. キャッシュに依存しない比較

  • == に頼るとキャッシュの有無で結果が変わり、バグの温床になる
  • プリミティブへアンボクシングしてから == を使うか、equals() を使用してください。

4. Null 安全な比較

4‑1. NPE を防ぐ書き方

Objects.equals(a,b) の内部実装は

なので、null チェックを毎回書く必要がなくなります

4‑2. 複数フィールドの比較例

Objects.equals を使うだけでコードがシンプルになり、レビュー時の見落としが減ります。


5. カスタムクラスにおけるベストプラクティス

項目 推奨実装
equals の基本形 if (this == o) return true;
if (!(o instanceof MyClass)) return false;
hashCode と整合性 Objects.hash(field1, field2 …) を使用
null 安全 Objects.equals で比較
同一性チェックに == を使うケース enum、シングルトン、Class<?> オブジェクトなど「インスタンスが唯一」な型

例:完全実装

  • hashCode を忘れると HashMap/HashSet で不整合が発生します。
  • equalshashCode は必ず対に実装しましょう。

6. コードレビュー時のチェックリスト

このリストをレビュー時に必ず確認すれば、比較バグの多くは未然に防げます


7. まとめ:安全な比較のための3つのルール

  1. 内容が重要なら equals()(または Objects.equals)を使う
  2. String、ラッパークラス、カスタムオブジェクトすべてに当てはまります。

  3. == は「同一インスタンスか」だけを判定したいときに限定する

  4. enum、シングルトン、Class<?> など唯一性が保証された型でのみ使用。

  5. キャッシュやオートボクシングに依存しないコードを書く

  6. ラッパークラスは常に equals()、またはプリミティブへアンボクシングしてから == を使う。

これらの指針を守れば、Java の比較に起因するバグは格段に減少し、保守性と可読性が向上します。ぜひ日常のコーディング・レビューで活用してください。

スポンサードリンク

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


-JAVA