カテゴリ: JavaSilver試験対策 更新日: 2026/03/24

Javaの同一性と同値性をわかりやすく解説!初心者向けの基礎知識

027
Javaの同一性と同値性

先生と生徒の会話形式で理解しよう

生徒

「Javaで2つのオブジェクトが同じかどうかを判定したいのですが、どうすればよいですか?」

先生

「それはJavaの同一性同値性を理解することが重要です。それぞれについて詳しく説明しますね。」

生徒

「同一性と同値性ですか?違いがよくわからないです。」

先生

「大丈夫ですよ!同一性はオブジェクトの参照が同じかどうか、同値性はオブジェクトの値が等しいかどうかを表します。これから詳しく説明していきますね。」

1. Javaにおける同一性とは?

1. Javaにおける同一性とは?
1. Javaにおける同一性とは?

Javaで「同一性」とは、2つの変数が同じインスタンスを参照していることを意味します。同一性の判定には==演算子を使用します。

例: 同一性を確認するコード


public class IdentityExample {
    public static void main(String[] args) {
        Object obj1 = new Object();
        Object obj2 = obj1; // obj1の参照をobj2にコピー
        System.out.println(obj1 == obj2); // trueが出力される
    }
}

このコードでは、obj1obj2は同じオブジェクトを参照しているため、==の結果はtrueになります。

2. 問題のコード解説

2. 問題のコード解説
2. 問題のコード解説

以下のコードを確認してみましょう。


public class Main {
    public static void main(String[] args) {
        Sample obj1 = new Sample(10);
        Sample obj2 = obj1;
        obj1 = new Sample(10);
        System.out.println(obj1 == obj2);
    }
}

このコードでは、以下のように処理が進行します:

  1. Sample型の新しいインスタンスを作成し、その参照をobj1に代入します。
  2. obj1の参照をobj2にコピーします。
  3. Sample型の新しいインスタンスを作成し、その参照をobj1に代入します。

その結果、obj1obj2は異なるインスタンスを参照しているため、==の結果はfalseになります。

3. 同一性と同値性の違い

3. 同一性と同値性の違い
3. 同一性と同値性の違い

Javaでは、同一性と同値性は以下のように区別されます:

  • 同一性: 2つの変数が同じオブジェクトを参照しているかどうか(==で判定)。
  • 同値性: 2つのオブジェクトの値が等しいかどうか(equals()メソッドで判定)。

例: 同一性と同値性の違いを確認するコード


public class EqualityExample {
    public static void main(String[] args) {
        String str1 = new String("Hello");
        String str2 = new String("Hello");
        System.out.println(str1 == str2); // false: 異なるインスタンスを参照
        System.out.println(str1.equals(str2)); // true: 値が等しい
    }
}

この例では、str1str2は異なるインスタンスですが、値が同じためequals()の結果はtrueになります。

Javaをこれから始める人や、 オブジェクト指向の考え方を基礎から理解したい人には、 定番の入門書がこちらです。

スッキリわかるJava入門 第4版をAmazonで見る

※ Amazon広告リンク

4. 注意点とコツ

4. 注意点とコツ
4. 注意点とコツ
  • オブジェクトの比較方法を理解する:オブジェクトの参照を比較する場合は==、値を比較する場合はequals()を使う。
  • 意図的な設計を:カスタムクラスで値の比較を行いたい場合、equals()メソッドをオーバーライドする。
  • デバッグの際のチェック:参照の比較と値の比較を混同しないように注意。

5. 実践課題

5. 実践課題
5. 実践課題

次のコードを試して、同一性と同値性の違いを確認してください:


public class Practice {
    public static void main(String[] args) {
        Sample obj1 = new Sample(20);
        Sample obj2 = obj1;
        obj1 = new Sample(20);
        System.out.println(obj1 == obj2); // 結果は?
    }
}

このコードの実行結果を確認して、obj1obj2が参照しているオブジェクトを理解しましょう。

6. メモリイメージで見る同一性と同値性

6. メモリイメージで見る同一性と同値性
6. メモリイメージで見る同一性と同値性

同一性と同値性の違いを理解するためには、コンピュータのメモリの中で何が起きているかを知るのが近道です。Javaでは、変数にはオブジェクトそのものではなく、オブジェクトが置かれている場所(住所)である「参照」が格納されています。

プログラミング未経験の方でも、以下の図解コードでイメージを掴んでみましょう。


public class MemoryVisualizer {
    public static void main(String[] args) {
        // インスタンスAを作成(住所: 0x100)
        String a = new String("Java"); 
        // インスタンスBを作成(住所: 0x200、中身は同じ)
        String b = new String("Java"); 
        
        // == は「住所(0x100と0x200)」を比較している
        System.out.println(a == b); 
        // equals は「中身("Java")」を比較している
        System.out.println(a.equals(b));
    }
}

実行結果:


false
true

このように、==演算子は「同じ箱を見ているか」を確認し、equals()メソッドは「箱の中身が同じか」を確認していると考えると分かりやすくなります。

7. 文字列リテラルとStringの特殊な挙動

7. 文字列リテラルとStringの特殊な挙動
7. 文字列リテラルとStringの特殊な挙動

Javaには、メモリを節約するための「文字列リテラル(String Pool)」という仕組みがあります。newを使わずに文字列を作成した場合、同じ文字列は同じ参照(住所)を共有することがあります。

これが原因で、==を使っても偶然 true になってしまうケースがあり、初心者が混乱するポイントです。


public class StringPoolExample {
    public static void main(String[] args) {
        String s1 = "Hello"; // String Poolに作成
        String s2 = "Hello"; // Pool内の同じ参照を再利用
        
        System.out.println(s1 == s2); // 参照が同じなので true になる!
    }
}

実行結果:


true

この挙動があるため、Javaでは「文字列の内容を比較したいときは、常に equals() を使う」というルールが徹底されています。リテラルの仕組みに頼って == を使うと、思わぬバグの原因になるため注意しましょう。

8. 同値性の判定ロジックを自作する

8. 同値性の判定ロジックを自作する
8. 同値性の判定ロジックを自作する

自分で作成したクラス(カスタムクラス)で equals() を使う場合、初期状態では == と同じ動き(同一性の比較)しかしてくれません。「どの項目が一致したら同じとみなすか」を自分で定義する必要があります。

以下の例では、IDが同じであれば同じユーザーであると判定するロジックを組んでいます。


class User {
    int id;
    User(int id) { this.id = id; }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true; // 同一なら即座にtrue
        if (obj instanceof User) {
            User other = (User) obj;
            return this.id == other.id; // IDが一致すれば同値とみなす
        }
        return false;
    }
}

public class CustomEquality {
    public static void main(String[] args) {
        User u1 = new User(123);
        User u2 = new User(123);
        
        System.out.println("同一性(==): " + (u1 == u2));
        System.out.println("同値性(equals): " + u1.equals(u2));
    }
}

実行結果:


同一性(==): false
同値性(equals): true

このように、プログラムの目的に合わせて「同値」の定義をカスタマイズできるのがJavaの柔軟な点です。実務では、この equals() の設計が非常に重要になります。

まとめ

まとめ
まとめ

Javaの同一性と同値性について学びました。同一性は==演算子を使って、2つの変数が同じオブジェクトを参照しているかを確認します。一方、同値性はequals()メソッドを用いて、オブジェクトの値が等しいかを確認します。これらを理解することで、コードの意図を正確に反映させることが可能になります。また、参照の変更や新しいインスタンスの生成が、結果にどのように影響を与えるのかを明確に理解することが大切です。

サンプルコード: 同一性と同値性の再確認


public class SummaryExample {
    public static void main(String[] args) {
        String value1 = "Java";
        String value2 = new String("Java");
        System.out.println(value1 == value2); // false: 異なる参照
        System.out.println(value1.equals(value2)); // true: 同じ値
    }
}

このコードでは、リテラルと新しいインスタンスを比較しています。==では異なる参照を持つためfalseを返し、equals()では値が同じであるためtrueを返します。

先生と生徒の振り返り会話

生徒

「同一性と同値性について、やっと理解できました!でも、コードを書くときにいつも混乱してしまいそうです。」

先生

「最初は混乱するかもしれませんが、基本を押さえれば大丈夫です。同一性は参照、同値性は値の比較と覚えておくと簡単ですよ。」

生徒

「これからは、コードを書くときに==equals()の使い分けを意識してみます!」

先生

「素晴らしい意識ですね!それに加えて、カスタムクラスで値の比較が必要な場合はequals()メソッドをオーバーライドするのも覚えておいてください。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Javaで「同一性」と「同値性」はどう違うのですか?

Javaにおける「同一性」とは、2つの変数が同じオブジェクトを参照しているかを意味し、「==」演算子を使って比較します。一方「同値性」とは、2つのオブジェクトの中身(値)が等しいかどうかで、「equals()」メソッドで比較します。

Javaの同一性を判定するには何を使えばいいですか?

Javaでは「==」演算子を使って同一性を判定します。これは2つの変数が同じインスタンス(参照)を指しているかどうかを確認する方法です。

Javaでオブジェクトの値が等しいかどうかを調べるにはどうしますか?

Javaでは「equals()」メソッドを使って、オブジェクトの値が等しいかどうか、つまり同値性を判定します。内容が同じでも別のインスタンスなら「==」ではfalseになります。
JavaSilver試験対策の一覧へ
新着記事
Flutter
Flutterでのリポジトリパターンの実装例
Flutterでリポジトリパターンを実装する方法を完全解説!初心者向けアーキテクチャ設計入門
Java
Java の Objects クラスを使って null チェックを簡単にする方法
JavaのObjectsクラスの使い方を完全ガイド!nullチェックを簡単・安全に行う方法
Java
Java の UUID クラスを使って一意の識別子を作成する方法
JavaのUUIDクラスの使い方を完全ガイド!初心者でもわかる一意な識別子の作成方法
Java
Java の古い日付クラス(Date, Calendar)と新しい日付 API の違い
JavaのDateとCalendarと新しい日付APIの違いとは?初心者向け完全ガイド
人気記事
Java
Java の Random クラスを使ってランダムな数値を生成する方法
JavaのRandomクラスの使い方を完全ガイド!初心者でもわかる乱数生成
Java
Java の getter メソッドと setter メソッドの使い方
Javaのgetterメソッドとsetterメソッドの使い方を完全ガイド!初心者でもわかるアクセス方法
AWS
【AWS】RDSの料金体系まとめ!ざっくり理解・高いと感じる理由も解説
【AWS】RDSの料金体系まとめ!ざっくり理解・高いと感じる理由も解説
AWS
【AWS】VPCとは?初心者向けに仕組み・用途・できることをわかりやすく解説
【AWS】VPCとは?初心者向けに仕組み・用途・できることをわかりやすく解説

🔌 USBポート不足を解消

Type-C 1本で拡張。
開発・作業環境を一気に快適に

UGREEN USB-Cハブを見る

※ Amazon広告リンク