たなかのJava日記

どんなことをやったか(学んだか)、どこで詰まったか(わからなかったか)、どこで工夫したかの記録です。

【Java】インスタンスの等価判定(疑問編)

【疑問点】
前回、インスタンスの等価判定を学びました。
【Java】インスタンスの等価判定(前編) - たなかのJava日記

その途中のequals()をオーバーライドする過程で、AをBで書くことができるのではないか?と思いました。

まず、Aのコードです。
これは前回の記事で作成したコードです。

        // aとbのインスタンスのコンビ名が等価(同じ内容)で無ければfalseを返す
        if (!this.combination.equals(p.combination)) {
            return false;
        }

        // aとbのインスタンスのnameが等価(同じ内容)で無ければfalseを返す
        if (!this.name.equals(p.name)) {
            return false;
        }

次にBのコードです。

        if (!(this.combination == p.combination)) {
            return false;
        }

        if (!(this.name == p.name)) {
            return false;
        }

【なぜ、AをBに変えられると思ったのか】
java.lang.Objectクラスに定義されているequals()の中身は「ただの等値判定」ロジックになっているためです。
要は同じアドレスかどうかを判定しています。
しかし、Aの場合行っていることは、等値判定ではなく等価判定です。
これは、同じ内容かを判断しています。
ということは、実はBが正しいやり方ではないかと思いました。
なぜなら、文字が同じ内容かを判断したいので==演算子で良いと思ったからです。
実際に==演算子であるBで実行すると問題ありませんでした。

しかし、いくら調べてみてもAの方法で行っていました。

【equals()の本当の正体とは・・?】
さらに調べると、実はAで行っているequals()はjava.lang.Objectクラスに定義されているものではなく、
java.lang.Stringクラスのequals()でした。
Stringクラスのequals()は文字列の値が等しいか判定を行います。
なので、いくら調べてもAの方法で行っていたのです。

【==演算子で文字列の比較について】
そもそも、==演算子での文字列の比較は等値判定(同じアドレスか)になってしまうので行うべきではありませんでした。
【Java】インスタンスの等価判定(前編) - たなかのJava日記

【まとめ】
文字列を比較するときは==演算子ではなくequals()を使用する。
なので、Bのやり方は間違っている。

java.lang.Objectクラスに定義されているequals()
⇒そのままでは「ただの等値(同じアドレスか)判定」ロジックになっている。
そのため、新しくクラスを作成したら、そのクラスでオーバーライドし、
適切と考える等価判定(同じ内容か)アルゴリズムを実装する必要がある。

java.lang.Stringクラスに定義されているequals()
⇒文字列の値が等しいか判定を行います。

java.lang.Stringクラスに定義されているequals()の公式ドキュメントを解説していた方がいました。
java.lang.Stringクラスのequalsメソッドのソースコードを読んでみた
Java equalsメソッドをオーバーライドするサンプル | ITSakura