【Java学習|初心者向け】Javaの「==」と「equals()」を正しく使い分けよう!同一性と同値性の違いを完全攻略

1. 導入:なぜ「==」で比較してはいけない時があるのか?

Javaでプログラミングをしていると、「値は同じなのに、なぜかif文でfalseになる」という経験はありませんか?これは、Javaにおける「同一性(Identity)」と「同値性(Equality)」の違いを理解していないことで発生する、初心者によくあるバグの一つです。この違いを知ることは、バグの少ない堅牢なコードを書くための第一歩です。

2. 基礎知識:同一性と同値性の違い

Javaの比較において、以下の2つの概念を区別する必要があります。

同一性 (Identity):メモリ上の「場所(アドレス)」が同じか。つまり、インスタンスそのものが同じかどうかを判定します。比較演算子「==」を使います。
同値性 (Equality):保持している「中身(値)」が同じか。インスタンスの内容が一致しているかどうかを判定します。メソッド「equals()」を使います。

基本データ型(int, booleanなど)は値そのものを持つため「==」で比較しますが、参照型(Stringや自作クラス)を「==」で比較すると、中身ではなく「メモリのどこに保存されているか」という住所を比較することになるため、意図しない結果を招きます。

3. 実装/解決策

オブジェクトの中身を比較したい場合は、必ず「equals()」メソッドを使用しましょう。ただし、equals()を自作クラスで使う際は、正しくオーバーライド(再定義)されている必要があります。また、最近のJavaでは「instanceof パターンマッチング」を使うことで、型チェックとキャストを安全かつ簡潔に行うことができます。

4. サンプルプログラム

以下のコードをコピーして、動作を確認してみてください。

public class ComparisonExample {
public static void main(String[] args) {
String str1 = new String(“Java”);
String str2 = new String(“Java”);

// 【同一性の比較】メモリの場所は別々なのでfalse
System.out.println(“== での比較: ” + (str1 == str2));

// 【同値性の比較】中身の文字列は同じなのでtrue
System.out.println(“equals() での比較: ” + str1.equals(str2));

// 【instanceof パターンマッチングの例】
Object obj = “Hello”;
// 型チェックと同時に変数sにキャストして代入する(Java 16以降)
if (obj instanceof String s) {
System.out.println(“中身は文字列です: ” + s.toUpperCase());
}
}
}

5. 応用・注意点:現場で陥りやすい罠

NullPointerExceptionに注意:
equals()を呼び出す際、左辺がnullだとエラーになります。比較対象がnullになる可能性がある場合は、”定数”.equals(変数) のように、定数を左側に置く「ヨーダ記法」を使うと安全です。

比較演算子の優先順位:
算術演算子(+ – /)は比較演算子より優先されます。また、論理演算子(&&, ||)はビット演算子(&, |)と混同しがちです。特に&&は「短絡評価(左側がfalseなら右側を評価しない)」を行うため、副作用のある処理を右側に書かないよう注意しましょう。

結論:
参照型の中身を比較する時は「equals()」、インスタンスそのものが同じか確認する時は「==」と覚えておけば、Javaの比較で迷うことはなくなります!

コメント

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