はじめに
インフラの分野でも、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