はじめに
インフラの分野でも、Iac化が進んで行くと考えています。そこで、ノウハウが体系だっているものが学び易いと考えて、Javaを学びはじめました。
今回は、equals
メソッドをオーバーライドして、Sample
クラスの2つのオブジェクトを比較する方法です。
間違い探し
public class Sample {
private int num;
public Sample(int num) {
this.num = num;
}
public boolean equals(Sample obj) {
if (obj == null) {
return false;
}
return this.num == obj.num;
}
}
public class main {
public static void Main(String[] args) {
Object a = new Sample(10);
Object b = new Sample(10);
System.out.println(a.equals(b));
}
}
1. equals
メソッドのオーバーライドに関する問題
まず、Sample
クラス内でのequals
メソッドはObject
クラスのequals
メソッドをオーバーライドするべきですが、シグネチャが少し間違っています。
-
Object
クラスのequals
メソッドは、Object
型の引数を受け取ります。したがって、Sample
クラスのequals
メソッドは、Object
型の引数を取るべきです。 - さらに、
Object
型の引数に対応するために、型キャストを行う必要があります。
☝️修正後のコードでは、equals(Object obj)
に変更します。
2. equals
メソッド内での型キャスト
equals
メソッドをオーバーライドする場合、引数として渡されたObject
型をSample
型にキャストする必要があります。キャストが失敗した場合のエラーを防ぐために、instanceof
を使って型チェックを行うことが一般的です。
修正後のコード
public class Sample {
private int num;
// コンストラクタ
public Sample(int num) {
this.num = num;
}
// equalsメソッドのオーバーライド
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // 同一オブジェクトであればtrueを返す
if (obj == null || getClass() != obj.getClass()) return false; // nullまたは異なるクラスならfalse
Sample sampleObj = (Sample) obj; // 型キャスト
return this.num == sampleObj.num; // numフィールドを比較
}
// hashCodeもオーバーライドすべき
@Override
public int hashCode() {
return Integer.hashCode(num); // numに基づいたhashCodeを返す
}
}
public class Main {
public static void main(String[] args) {
Object a = new Sample(10);
Object b = new Sample(10);
System.out.println(a.equals(b)); // trueを出力するはず
}
}
-
equals(Object obj)
メソッドのオーバーライド-
equals
メソッドをObject
型の引数を取るように変更しました。これにより、Object
クラスのequals
メソッドを正しくオーバーライドすることができます。 -
this == obj
を最初にチェックすることで、同一オブジェクトであれば即座にtrue
を返します。 -
obj == null || getClass() != obj.getClass()
で、obj
がnull
か、異なるクラスである場合はfalse
を返します。これにより、型の不一致を防ぎます。 -
Sample sampleObj = (Sample) obj;
で、obj
をSample
型にキャストします。 - 最後に
this.num == sampleObj.num
で、num
フィールドを比較して、オブジェクトが等しいかどうかを判断します。
-
-
hashCode
のオーバーライド-
equals
メソッドをオーバーライドした場合、hashCode
メソッドもオーバーライドすることが推奨されます。hashCode
はequals
と一貫性を持つ必要があるため、num
フィールドを元にしたhashCode
を生成します。
-
出力結果
true