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

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

ただいまの
回答率

90.51%

  • Java

    15831questions

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

equalsメソッドの使い方、instance ofの使い方がわかりません。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,291

k_mail

score 71

iJava SE7 Silver の資格を目指し勉強中です。

長文で申し訳ありません。
要領を得ない質問なので、わかるところだけでも回答していただけると嬉しいです。

分からない点は
 ・8行目のequalsメソッドの使い方
  ・8行目のequalsメソッドの引数(Object obj)
  ・9行目のnull
 ・12行目のifはelse ifのことか?
 ・12行目に出てくるinstance ofの使い方
  ・13行目の(Sample)
  ・12~15行目で何をしているのかがわかりません。

1 public class Sample{
2    private int num;
3    private String name;
4    public Sample(int num, String name){
5        this.num = num;
6        this.name = name;
7    }
8    public boolean equals(Object obj){
9        if(obj == null){
10      return false;
11       } 
12       if(obj instanceof Sample){
13          Sample s = (Sample) obj
14      return s.num == this.num
15       }
16       return false;
17    }
18 }

↑このクラスを利用する、以下のプログラムをコンパイル、実行したときの結果は?

1 public class Main{
2     public static void main(String@: args){
3        Sample a = new Sample(10, "a");
4         Sample b = new Sample(10, "b");
5         System.out.println(a.equals(b));
6     }
7  }

答えは「trueと表示される」です。

メインクラスの5行目 System.out.println(a.equals(b));  でaの参照先とbの参照先が同じかと
聞かれていると解釈しました。

equals(b)でequalsメソッドが呼び出されているのでSampleクラスのequalsメソッドを見ます。そこで引数の中身が
(Object obj)となっています。これは例えば(int num)のように考えて(Object obj)はオブジェクトしか引数として受け入れないということでしょうか。

そして、Sampleクラス9行目の if(obj == num)は引数が何も参照しない、
つまり、 Sample b = new Sample(10, "b");が
     Sample b = new Sample();の時を表しているのでしょうか

そして、12~15行目のifのブロック{}では何をしているのでしょうか。

よろしくお願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+4

equalsメソッドについてはargiusさんがおっしゃってる通りですので
自分は、Mainクラスの説明を。(長文ごめんなさい。)

   Sample a = new Sample(10, "a"); 
   Sample b = new Sample(10, "b"); 

これによって、Sample型のaという名前のハコとbという名前のハコが用意され、
ぞれぞれの引数によって、フィールドに値が設定されます。
(newされれば、それぞれSampleクラスのメンバが準備される辺りは大丈夫ですよね?)

Sample型`a`のハコの中身
  ├ int    num10String name ⇒ "a"

Sample型`b`のハコの中身
  ├ int    num10String name ⇒ "b"

で、このハコ同士をequalsメソッドで比較しています。

a.equals(b);

これでaのハコにあるequalsメソッドを使って、引数bを評価します。

Sampleクラスのequalsメソッドでは2つのif文条件がありました。
 1. 引数objがnullかどうか
 2. 引数objがSampleクラスのインスタンスかどうか

1.についてですが、bはnewされてインスタンスが用意されていますので、
nullではない、つまり 評価はfalseになります。

続いて2.についてですが、bの型はSample型ですので、評価はtrueになり、if文の中に処理が進みます。
13行目の

Sample s = (Sample) obj;

では、引数でObject型とされていたので、改めてオブジェクトをSample型にキャストして、Sample型の変数sに格納しています。
キャストについてはコチラを参照してください。

これにより、sbは同じものを参照することになります。
そして、

s.num == this.num;

ハコsのフィールドnum(=ハコbのフィールドnum) の値が、ハコaのフィールドnumと同じかどうか、比較しています。
↑に書いた図にもあるように、aのnumにもbのnumにもそれぞれ 10 という数値が格納されていますので、
この比較の結果は trueとなり、メソッド呼び出し元へreturnされます。


あとは、その他の疑問点についてです。
1点目。

・12行目のifはelse ifのことか?

ちがいます。

if(条件A){~}
if(条件B){~}


は、条件Aも条件Bも結果がどうであれ実行されますが、

if(条件A){~}
else if(条件B){~}


とelseでつなげてしまうと、条件Aの結果がfalseの場合は条件Bが評価されますが、
条件Aの結果がtrueの場合は条件Bは評価されずに処理が先に行ってしまいます。

ま、この場合結果として同じfalseが返るのですが、これを混同させてしまうとあとで痛い目にあいます。

2点目。

そして、Sampleクラス9行目の if(obj == num)は引数が何も参照しない、 
つまり、 Sample b = new Sample(10, "b");が 
     Sample b = new Sample();の時を表しているのでしょうか

これも違いますね。
何も参照しないのは、nullです。
Sample b = new Sample(10, "b");
でも
Sample b = new Sample();
でも、インスタンスは作成され、nullではなくなります。

あと、余談ですが、このSampleクラスには、引数なしコンストラクタは定義されていませんので、
Sample b = new Sample();
と記載するとコンパイルエラーになります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/09 16:03

    丁寧なご回答ありがとうございます。
    1つ理解できなところがありました。

    Sampleクラスのequalsメソッドでは2つのif文条件がありました。
    1. 引数objがnullかどうか
    (中略)
    1.についてですが、bはnewされてインスタンスが用意されていますので、
    nullではない、つまり 評価はfalseになります。

    最後の評価がなぜfalseになるのかです。
    if(obj == null){
    10 return false;
    これはnullの時にfalseを返すのであって、nullでない時はfalseを返さない(無視する)なのではと思うのですが、どこが間違っているのでしょうか

    キャンセル

  • 2016/02/09 16:59

    横から失礼します。
    ここで言っているのはifの中のobj == nullの評価です。
    ここではobjにはオブジェクトが実在しており、nullではないためfalseになります。
    そのため、このif文はスキップされます。

    キャンセル

  • 2016/02/09 17:27

    swordoneさん、フォローありがとうございます!

    if文は、条件が満たされる(結果がtrueになる)場合にのみ、
    {}中の処理へ進めるんです。
    なので、10行目のreturnは切り離して考えてください。

    キャンセル

  • 2016/02/09 21:59

    kaputarosさん

    返信が遅くなりました。
    falseの評価はif文全体ではなく、()の中に対してだったのですね。
    勘違いしていました。
    何度も有難うございました。

    swordoneさん
    コメントありがとうございます。
    また、質問見ていただいていたのですね。
    嬉しいです。
    有難うございました。

    キャンセル

+3

まず、

if(obj == num)


は、おそらく

if(obj == null)


としたいのではないでしょうか。
つまり、比較対象のオブジェクトがnullなら常にイコールではないということを表そうとしているのだと思います。
そもそも、これはコンパイルエラーになります。

次に、

if(obj instanceof Sample){
    Sample s = (Sample) obj
    return s.num == this.num
}


の部分は、比較対象のオブジェクトがSampleクラスのインスタンスである(obj instanceof Sample)なら、numフィールドの値が等しいかどうかでオブジェクトがイコールかどうかを決めるようにしています。

引数の中身が(Object obj)になっているのは、このメソッドがObjectクラスのオーバーライドメソッドだからです。
あらゆるオブジェクトがequalsで比較可能なのはそのためです。
標準ライブラリーのソースコードを見てみると分かりますが、equals(Object)とは別に、オーバーライドでないオーバーロードメソッド、例えばequals(String)のようなメソッドを持っているクラスもたくさんあります。


参考リンク:

Java 基礎知識( オブジェクトの比較 )【 Okapi Project 】
http://www.okapiproject.com/java/java_ref/foundation/manual_06.htm

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/09 14:39

    ご返信ありがとうございます。
    nullに変更しました。

    キャンセル

  • 2016/02/09 15:30 編集

    Java 基礎知識( オブジェクトの比較 )【 Okapi Project 】
    http://www.okapiproject.com/java/java_ref/foundation/manual_06.htm
    拝見しました。

    『1. オブジェクトの比較』では
    オブジェクトに格納されている値を比較するには、 epuals( ) メソッドを利用します。
    『2.1. equals() メソッドの実装』では、
    Object クラスが実装する equals( ) メソッドは参照値が同じであることを評価するため、(自分で作成したクラスで値の同値性を評価したい場合は、equals( ) メソッドを実装しなければいけません。)
    とあります。

    『1. オブジェクトの比較』では「格納されている値(参照値でない)」一方、
    『2. 1equals() メソッドの実装』では「参照値(メモリのアドレス)」となっているのはなぜでしょうか。
    それとも何か勘違いしているのでしょうか

    キャンセル

  • 2016/02/09 15:52 編集

    「Object クラスが実装する equals( ) メソッドは参照値が同じであることを評価するため」確かにこの部分は少し分かりにくいですね。

    もう少し分かりやすく言い換えると、
    「Objectクラスが実装している equals( ) メソッドは、参照値が同じであることを評価する実装(つまり==と同じ)になっているため」です。
    なので、equals(Object)メソッドをオーバーライドしないと、==とequalsは意味が同じになってしまいます。
    全く同じインスタンス以外でもequalsがtrueになるようにするには、equals(Object)メソッドをオーバーライドしないといけないのです。

    キャンセル

  • 2016/02/09 22:05 編集

    返信が遅くなり申し訳ございません。
    equals(Object)メソッドをオーバーライドしないと、==とequalsは意味が同じになってしまうのですね。
    素晴らしい回答有難うございます。
    今回ベストアンサーを決めかねたのですが、スコアを見て別の方を優先させていただきました(スコアと関係あるのかよく分かっていませんが。。。)
    参考リンクも貼っていただき、非常に勉強になりました。
    有難うございました。

    追記
    失礼ながら勝手にフォローさせていただきました。

    キャンセル

  • 2016/02/09 22:20

    ご解決されたようで良かったです。

    また、フォローしていただきありがとうございます。

    キャンセル

同じタグがついた質問を見る

  • Java

    15831questions

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