aymnkt
@aymnkt

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

.equalsメソッドの扱いについて

解決したいこと

  • .equals()メソッドの、引数にオブジェクト型を入れた場合と、それ以外のオブジェクトを入れた場合の動作について。

自分で試したこと

ネット等で調べた結果、

Object a = new test(10);
Object b = new test(10);
System.out.println(a.equals(b));

とすると、

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

が呼び出されて、同一性の比較が行われ、falseとなる。という理解ですが、これは合っていますでしょうか。
又、オーバーライド前提であるとのことですが、これは処理{}部分において指定条件を変えるためという認識で合っていますでしょうか。返り値はboolean型ならOKということでしょうか。

  • 以下のように記述した場合、同値性の比較になるようですが、具体的に何かメソッドが呼び出されて処理された結果なのか、a.equals(b)だけで処理されるのか知りたいです。
String a = "a";
String b = "a";
System.out.println(a.equals(b));
0

5Answer

同一性の比較が行われ、falseとなる

あっています

オーバーライド~指定条件を変える

あっています

具体的に何かメソッドが呼び出されて処理された結果なのか、a.equals(b)だけで処理されるのか

質問の意図をはかりかねるため、String#equalsの実装を提示します。
最終的にはStringLatin1#equalsでbyteを順に比較しています。

String#equals

static final boolean COMPACT_STRINGS;

static {
  COMPACT_STRINGS = true;
}
public boolean equals(Object anObject) {
  if (this == anObject) {
    return true;
  }
   return (anObject instanceof String aString)
     && (!COMPACT_STRINGS || this.coder == aString.coder)
     && StringLatin1.equals(value, aString.value);
}

StringLatin1#equals

public static boolean equals(byte[] value, byte[] other) {
  if (value.length == other.length) {
    for (int i = 0; i < value.length; i++) {
      if (value[i] != other[i]) {
        return false;
      }
    }
    return true;
  }
  return false;
}
0Like

Comments

Objectのequalsメソッドは、オブジェクトのインスタンスが比較されるので、インスタンスが異なればfalseとなります。

Stringのequalsメソッドは、文字そのものを比較する実装となっているので、インスタンスは異なっていても、保持する文字(列)が一致すればtrueになります。

0Like

Comments

  1. @aymnkt

    Questioner

    @nak435 さん、ありがとうございます。

質問文からはどうとでも取れるのですが、なんとなくメソッドのオーバーライドについて関心があるように見受けましたので、一点だけ注記しておきます。
それは、オーバーライドが式の静的な型でなく、実行時のインスタンスの型によって判断されるということです。
(この点、オーバーロードと対照的で、だからこそ依存性の反転などの重要なテクニックが可能となります。)

なので、

Object a = new test(10);
Object b = new test(10);
System.out.println(a.equals(b));

この場合でも、testクラス(普通はTestとします)でequalsメソッドがオーバーライドされていれば、それが真っ先に参照されます。
それが「同値性」に基づいた実装であれば、呼び出し元のこのコードは同じままでtrueが返る可能性もあります。
オーバーライドの解決は実行時になされ、その過程においてaやbがObjectとして宣言されていることは関与しません。

又、オーバーライド前提であるとのことですが、これは処理{}部分において指定条件を変えるためという認識で合っていますでしょうか。返り値はboolean型ならOKということでしょうか。

はい。
親クラスの既定の振る舞いを上書きすることが、オーバーライドの主要な目的の1つです。
基本的に返り値を含めたシグネチャが合っていればオーバーライドとして成立しますが、
equalsの場合はそれに加えて「hashCodeの結果と整合的であること」という“規約”があるので、
具体的なもので実践する際はお気をつけください。

0Like

Comments

  1. @aymnkt

    Questioner

    @eudika さん、ありがとうございます。オーバーライドする型によってという観点が抜け落ちていました。

Your answer might help someone💌