2016-12-19 10 views
1

をコンパイルされたのはなぜのhashCode()のequals()メソッドので、私は間違っている可能性の多くをオーバーライドしていない このJavaコードが正常に

dep1.equals(emp2)がされている場所私の質問は、最後の行のためにあります正常にコンパイル(なぜ)(彼らはさまざまな種類を持っているように、私はコンパイルエラーを期待してい)と私はCHECKIいますので、コンパイルした後、私は私が15 15真を期待してい

15 15 false 

を以下の取得equalsメソッドでハッシュコードを作成します。

クラス EmployeeDepartmentの両方がまだ Objectクラスから継承されたメソッド public boolean equals(Object obj)をオーバーライドしていないためだ
class Employee { 
    private String name; 
    private int id; 

    public Employee(String name, int id) { 
     this.name = name; 
     this.id = id; 
    } 


    public int hashCode() { 
     return this.id; 
    } 

    public boolean equals(Employee employee) { 
     return this.hashCode() == employee.hashCode(); 
    } 


    public int getEmployeeId() { 
     return this.id; 
    } 
} 

class Department { 
    private String name; 
    private int id; 

    public Department(String name, int id) { 
     this.name = name; 
     this.id = id; 
    } 

    public int hashCode() { 
     return this.id; 
    } 

    public boolean equals(Department department) { 
     return this.hashCode() == department.hashCode(); 
    } 


    public int getDepartmentId() { 
     return this.id; 
    } 
} 


public class JavaCollections { 
    public static void main(String args[]) { 
     Employee emp2 = new Employee("Second Employee", 15); 

     Department dep1 = new Department("Department One", 15); 

     System.out.println(dep1.hashCode()+" "+emp2.hashCode()+" " + dep1.equals(emp2)); 
    } 
} 
+5

によって

public boolean equals(Department department) { return this.hashCode() == department.hashCode(); } 

を置き換える15 15真であるとウル答えが必要な場合は、 '私は')(かなりのhashCode()とequalsのオーバーライドされていません、正確には、実際にオーバーロードしたときに 'Object#equals'をオーバーライドしませんでした。これをオーバーライドするには、メソッドが 'public boolean equals(Object)'のように見える必要があります。 – SomeJavaGuy

+5

'equals(Object obj)'をオーバーライドしなかった場合、パラメータはメソッドのシグニチャの一部です。 '@ Override'アノテーションを追加することも考えてください。これはこのタイプの間違いを避けるでしょう。 – Berger

+3

したがって、呼び出されるメソッドが 'equals(Object o)'なので、コンパイラエラーは発生しませんでした。コンパイラには合法ですが、実装が別のDepartmentオブジェクトを必要とするため、実行時例外が発生します。 – arcy

答えて

3

まず、Javaのすべてのクラスがjava.lang.Objectのメソッドを継承し、equals(Object)メソッドを継承し、デフォルトの実装を提供する理由で、これは、あなたが提供したのオーバーロードであるのいずれかではなく、EmployeeDepartmentを比較するときに呼び出す方法です。

equalsコードは、実際には実行しなかったときに、equalsを上書きしているとコンパイラが認識していないため、正常にコンパイルされます。コンパイラは、あなたが他のDepartmentオブジェクトにDepartmentオブジェクトを比較するための新しい方法

public boolean equals(Department department) 

を作りたいと思います。

あなたはこのように、スーパークラスのメソッドをオーバーライドするコードを書く、それに@Override注釈を追加している場合:

@Override 
public boolean equals(Department department) 

今コンパイラが正しく方法は、実際のオーバーライドではないことをあなたに文句を言うでしょう基本クラスのメソッドで、コンパイル時に問題を警告します。

@Override 
public boolean equals(Department obj) { 
    if (obj == null || !(obj instanceof Department)) { 
     return false; 
    } 
    Department dept = (Department)obj 
    return dept.id == id; 
} 

注:equalsの署名は、Objectを取る@Overrideを追加し、nullのために、正しいタイプをチェックし、キャストを行い、その後、実際の比較を行うために、コードの変更を修正するには

この

return this.hashCode() == department.hashCode(); 

ようequalsを実装することは非常に壊れやすいです。あなたのケースでは動作しますが、hashCodeが他の実装(例えば、idnameの両方を考慮する実装)に置き換えられたとき、ハッシュコードがオブジェクトの一意のIDである場合、これはコードリファクタリングで生き残ることはできません。 IDの比較に頼るには、hashCodeを呼び出すことなくIDを直接比較してください。

1

このメソッドは、では、public boolean equals(Department department)ではなく呼び出されます。

具体的には、JLSを読み、以下のすべてが真であるときに限り

MCは内で宣言またはクラスCによって継承されたインスタンスメソッドは、CからmAのクラスAで宣言された別のメソッドをオーバーライド: を.. mCのシグネチャは、mAのシグネチャのサブシグネチャ(8.4.2)です。

この場合

boolean equals(Department department)boolean equals(Object obj)サブシグニチャはありません。

0

最初に、このコードdep1.equals(emp2)は、オブジェクトクラスのデフォルト実装を呼び出します。

第2に、特定のカスタマイズされたタイプの等価メソッドをオーバーライドして、両方のクラスでデフォルト実装をオーバーライドしませんでした。

uは

@override 
public boolean equals(Object department) { 
     return this.hashCode() == department.hashCode(); 
    } 
関連する問題