「==」と「equals」の違い②~同一性と同値性~

Java Silver

前回(「==」と「equals」の違い①~同一性と同値性~)の続き

同一性と同値性

Javaにおいて、

同一性とは、「同じインスタンスを参照している」性質のことで、

同値性とは「インスタンスは異なっていても、同じ値である」性質のことです。

以下の場合、xとyは同値です。

String x = new String("AAA");
String y = new String("AAA");

そして、同値性は、「equalsメソッド」で判定することが可能です。

System.out.println( x.equals(y) ); ⇒ true

equalsメソッド

equalsメソッドは、Objectクラスに定義されているメソッドで、以下のように定義されています。

Objectクラスのequalsメソッド

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

見てわかる通り、「==演算子」でthisとobjを判定しています。

「==演算子」は同一性(同じインスタンスを参照している性質)の判定をするためのものです。

Objectクラスのequalsメソッドはオーバーライドされることを前提にしているため、オーバーライドしなかった場合は、同値性ではなく、同一性を判定することになります。

「同じ値である」という定義は、「全フィールドが一致していること」なのか「あるフィールドのみが一致していること」なのか、クラスよって異なる部分です。

クラスごとに異なる「同じ値である」という定義は、設計者が定める必要があり、これをequalsメソッドのオーバーライドによって実現します。

ちなみに、Stringクラスでもequalsメソッドをオーバーライドしており、中身はわかりませんが、以下のように定義されています。

public boolean equals(Object anObject)

この文字列と指定されたオブジェクトを比較します。引数がnullではなく、このオブジェクトと同じ文字シーケンスを表すStringオブジェクトである場合にだけ、結果はtrueになります。

冒頭で例に出したコードは以下のように解釈できます。

String x = new String("AAA");
String y = new String("AAA");
System.out.println( x.equals(y) ); ⇒ true

引数がこのオブジェクト(xのこと)と同じ文字シーケンスを表すStringオブジェクト(yのこと)である場合にだけ、結果はtrue になる。

基本的にequalsメソッドを使う場面ではStringクラスを使用しているケースが多いので、「==演算子」と「equalsメソッド」の使い分けを意識することが多いと思いますが、

equalsメソッドはオーバーライドして使うものなので、以下のように独自でカスタマイズすることも可能です。

class Hoge{
  //フィールド
  int num;
  String str = "HOGE";

 //コンストラクタ ⇒ numを設定
  public Hoge(int num){
    this.num = num;
  }
  
 //equalsメソッドのオーバーライド
  public boolean equals(Hoge obj){
    return this.num == obj.num ;
  }
}

//処理実行クラス
public class Fuga{
  public static void main(String[] args){
    Hoge h1 = new Hoge(100);
    Hoge h2 = new Hoge(100);

    System.out.println(h1.equals(h1)); ⇒ true
  ⇒ Hogeクラスのequalsメソッドは「変数num」の値が同じであれば、trueを返す
  ⇒ このように、equalsメソッドはオーバーライドして独自に実装できる
  }
}


コメント

タイトルとURLをコピーしました