質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

4752閲覧

【Java Silver】(黒本の問題)equalsメソッドをオーバーロードし同一性を比較させるコードについて

moritat-222

総合スコア19

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1グッド

0クリップ

投稿2020/09/30 14:29

編集2020/10/01 14:25

#Java Silver黒本、第三章10問に関する質問です。

java

1package model; 2 3public class Sample{ 4 private int num; 5 public Sample(int num){ 6 this.num = num; 7 } 8 public boolean equals(Sample obj){ 9 if(obj==null){ 10 return false; 11 } 12 return this.num == obj.num 13 } 14} 15

java

1import model.*; 2 3public class MyApp { 4 public static void main(String[] args){ 5 Object a = new Sample(10); 6 Object b = new Sample(10); 7 System.out.println(a.equals(b)); 8 } 9} 10

このプログラムでMyAppのmainメソッドを実行すると「false」と表示される理由についてお伺いしたいです。

Sampleクラスに定義されているequals()メソッドでは、「this.num == obj.num」を比較しているため、
numフィールドが10のインスタンスaとnumフィールドが10のインスタンスbを比較すると「true」が返ると思うのですが、
実際は「false」が返ってきます。

#黒本の解説(引用)

インスタンスの同値性を確認するには、equalsメソッドを使うことを学びました。equalsメソッドはObjectクラスに定義されている全てのクラスが持っています。しかし、同値性の確認方法は各クラスによって異なるため、equalsメソッドはオーバーライドして使うことを前提としています。Objectクラスのequalsメソッドの定義は次の通りです。

java

1public boolean equals(Object obj){ 2 return (this == obj); 3}

設問のSampleクラスに定義されているequalsメソッドは、引数にObject型ではなくSample型を受け取ります。これはメソッドのオーバーロードです。

そのため、mainメソッドでObject型の引数を渡してequalsメソッドを呼び出した時は、Objectクラスに定義されたequalsメソッドが実行されます。

Objectクラスに定義されているequalsメソッドは、前述の定義からもわかる通り、同一性の判定をします (※ここが一番理解できません)

なぜObjectクラスに定義されているequalsメソッドが同一か(同じインスタンスか)を比較するものとなるのでしょうか

#考えたこと

原則、「==」が同一性を比較するもので、「equals()」が同値性を比較するものです。

上記の解説の通り、Objectクラスのequalsメソッドは同一性を比較する物であるとしても、

java

1 return this.num == obj.num

というコードはnumフィールドの値のみを比較しているように思えるため、あまりしっくりきません。

しかし、本当にnumフィールドだけを比較しているならばtrueを返すはずのコードが、実際はfalseを返しているので、黒本の解説が間違っている訳ではないように思います。

なぜ、上記のプログラムでMyAppのmainメソッドを実行すると「false」と表示されるのでしょうか。
よろしくお願いいたします。

mim_s👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Soei

2020/09/30 17:39

Sampleクラスのequalsは引数の型が異なるので、Objectクラスのequalsメソッドをオーバーライドしていません。 本当にこう記載されていたのだとしたら、解説の誤りです。
quickquip

2020/10/01 05:06

> 上記のコードは、equalsメソッドをオーバーライドして、インスタンスどうしの同一性を比較するものにされていると解説されていました。 この部分、文を正確に引用した方がよいように思いました。
moritat-222

2020/10/01 13:43

質問への修正依頼をいただき、ありがとうございます。 Objectクラスのequalsメソッドは、「オーバーライド」ではなく「オーバーロード」の間違いでした。 また、解説の意図を理解できていない私が要約しようとするよりは、と考え、解説部分の引用を増やしました。コメントいただき大変ありがとうございます。
guest

回答2

0

ベストアンサー

そもそも、Object#equalsの目的は、「自分自身と引数が等しい(同値である)かどうか判定する」というものです。
おおもとのObjectクラスにおいては、具体的な比較内容が存在しないため、便宜上同一性と同じ内容でequalsを定義しているだけの話です。
Sampleクラスにおいては、フィールド変数numが同じであれば等しいと見なそう、という形でequalsを定義しているのです。

10/2追記

よく見ると、これオーバーライドではなくオーバーロードなのですね。
今、Sampleクラスには

  • Objectクラスから継承したequals(Object)

==で比較するのと同じ効果のメソッド

  • Sampleクラスで新たに定義したequals(Sample)

フィールド変数で比較するメソッド

の2つのequalsメソッドが共存している形になります。

java

1import model.*; 2 3public class MyApp { 4 public static void main(String[] args){ 5 Object a = new Sample(10); 6 Object b = new Sample(10); 7 System.out.println(a.equals(b)); 8 } 9}

このコードではSampleオブジェクトがObject型に入っているため、呼び出されるequalsメソッドは前者のものになります。そうなると、当然異なるオブジェクトであるaとbに対してはfalse判定となります。

投稿2020/09/30 16:09

編集2020/10/01 19:53
swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moritat-222

2020/10/01 13:46

回答ありがとうございます。 私も、Sampleクラスにおいては、フィールド変数numが同じであれば等しいと見なそう、という形でequalsを定義しているように読み取れるのですが、実際コードを動かして見ると、フィールド変数が同じてもfalseが返ってきます。 黒本からの引用部分が少なかったため、判断いただく情報量が少なかったことを反省し、質問内容を修正致しました。 もしよろしければ、なぜフィールド変数numが同じでもfalseが返ってくるか、お教えいただきたく思います。よろしくお願いいたします。
moritat-222

2020/10/02 14:24

回答いただき大変ありがとうございます。 ということは、 ・Sampleクラスで定義されているequalsメソッドは、Sample型の引数を渡した時のみ動くメソッド ・mainメソッドの中のequalsメソッドでは、Object型の引数が渡されている ・この時、動くのはObjectクラスにデフォルトで定義されているequalメソッド ・Objectクラスにデフォルトで定義されているequalsメソッドは、同値かではなく同一かを判定する ・故に、mainメソッドの中の「a.equals(b)」はaとbが同一かを判定している ということですね。 スッキリしました。大変ありがとうございます。
swordone

2020/10/02 17:08

> ・Sampleクラスで定義されているequalsメソッドは、Sample型の引数を渡した時のみ動くメソッド 違います。Sampleクラスで定義されているequalsメソッドは、Sample型の変数に対してしか使えないメソッドなのです。Object型の変数に入っているオブジェクトからは、Sampleクラスのequalsメソッドは見えない状態になります。
guest

0

上記のコードは、equalsメソッドをオーバーライドして、インスタンスどうしの同一性を比較するものにされていると解説されていました。

それは間違い、というだけのはなしですね。

投稿2020/09/30 14:54

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問