2016-12-19 68 views
1

我還沒有覆蓋多的hashCode()的equals()方法所以我可能是錯的 我的問題是最後一行,其中爲什麼這個Java代碼編譯成功

dep1.equals(emp2)是被編譯成功(爲什麼)(我期待,因爲他們有不同類型的編譯錯誤),我得到以下

15 15 false 

編譯後在那裏我期待15 15真正因爲我checki ng方法中的哈希碼。

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(); } 

'我還沒有覆蓋的hashCode()和equals多的()',確切地說,實際上你沒有重寫'Object#equals',因爲你只是重載了它。重寫它將需要該方法看起來像「公共布爾等於(對象)'。 – SomeJavaGuy

+5

您沒有重寫'equals(Object obj)',這些參數是方法簽名的一部分。還要考慮添加'@ Override'註釋,這將避免這種類型的錯誤。 – Berger

+3

因此,你沒有得到編譯器錯誤,因爲被調用的方法是'equals(Object o)';對編譯器來說是合法的,但會給出一個運行時異常,因爲它的實現需要另一個Department對象。 – arcy

回答

3

首先,爲什麼這個編譯的原因:在Java中所有的類都是從java.lang.Object繼承,它定義equals(Object)方法,並提供了一個默認的實現。當您比較EmployeeDepartment,而不是您提供的過載時,這是您調用的方法。

您的equals代碼編譯得很好,因爲編譯器並不知道您實際上沒有認爲您重寫了equals。編譯器認爲你想一個新的方法

public boolean equals(Department department) 

比較Department對象與其它Department對象。

如果你正在編寫覆蓋超類的方法的代碼,添加@Override註釋,就像這樣:

@Override 
public boolean equals(Department department) 

現在,編譯器會正確地向你抱怨你的方法實際上不覆蓋一個在其基類中的方法,在編譯時提醒您這個問題。

要修復您的代碼更改equals簽名採取Object,加@Override,檢查null和正確的類型,做演員,然後做實際的比較:

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

注意:這樣

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

實施equals是非常脆弱的。雖然它適用於你的情況,但是當散列碼是對象的唯一ID時,如果hashCode被替換爲其他一些實現(例如,同時考慮idname的實現),代碼重構將無法繼續。如果您想依靠比較ID,請直接比較ID,而無需致電hashCode即可獲取它們。

1

這是因爲這兩個類EmployeeDepartment還沒有重寫的方法public boolean equals(Object obj)Object類繼承。

確切地說,這個方法在dep1.equals(emp2)而不是public boolean equals(Department department)中被調用。

更具體地,讀JLS

實例方法的MC聲明或C類繼承的,選自C覆蓋的另一種方法毫安在A類聲明,當且僅當滿足以下所有條件都爲真: .. mC的簽名是mA簽名的子簽名(§8.4.2)。

在這種情況下boolean equals(Department department)不是boolean equals(Object obj)子簽名。

0

首先,這段代碼dep1.equals(emp2)調用Object類的默認實現。

其次,U沒有重載默認實現在你的類中,因爲無法覆蓋特定自定義類型的平等方法。

如果妳需要烏爾答案是15 15真正

通過

@override 
public boolean equals(Object department) { 
     return this.hashCode() == department.hashCode(); 
    }