【疑問点】
前回、インスタンスの等価判定を学びました。
【Java】インスタンスの等価判定(前編) - たなかのJava日記
その途中のequals()をオーバーライドする過程で、AをBで書くことができるのではないか?と思いました。
まず、Aのコードです。
これは前回の記事で作成したコードです。
if (!this.combination.equals(p.combination)) {
return 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