2012-10-26 43 views
1
public class Dog 
{ 
    int collarID; 
    String name; 
    public static void main(String[] args){ 
     Dog d = new Dog(); 
     d.name="hose"; 
     System.out.print(d.hashCode());    
    } 

    public boolean equals(Object arg0) 
    { 
     if (arg0 instanceof Dog) 
     { 
      Dog new_name = (Dog) arg0; 
      return collarID==new_name.collarID && new_name.name.equals(name); 
     } 
     return false; 
    } 

    public int hashCode() 
    { 
     return toString().length();//StackOverflow 
    } 
} 

我錯過了什麼?是否因爲默認的toString()方法而對hashCode()方法進行反覆調用?爲什麼我不能使用toString().length()作爲hashCode()返回?

+0

@Rohit耆那教的回答解釋了堆棧溢出。但我會建議不要生成一個字符串來獲取哈希碼。在這種情況下,爲什麼不使用'collarID^String.valueOf(name).hashCode()'? –

+0

這是我在模擬考試中做錯的一個問題 – Joe

+0

我明白了。那麼這肯定是一個令人討厭的驚喜。爲了將來的參考,假設Java嘗試使默認實現不平等,直到您另有說明爲止,這是一個很好的經驗法則。這導致更少的意外行爲。爲此,未定義「toString」,「equals」,「hashCode」的類的實例將顯示不同的字符串和散列碼,並說它們不相等。 –

回答

12

如果你看到ObjecttoString方法的源代碼,它看起來像: -

public String toString() { 
    return getClass().getName() + "@" + Integer.toHexString(hashCode()); 
} 

所以,它在內部調用hashCode()方法。現在,由於您已經改寫了hashCode方法,因此它會調用您的班級的hashCode方法,該方法再次調用Object類的toString方法。

這無疑會導致StackOverFlowError

可以,而覆蓋toString方法類,以使其發揮作用。

P.S: -

但是,你hashCode實現的設計應考慮你在equals方法使用的屬性,以維持contractequals之間hashCode方法。在計算hashCode時只使用那些attributes,您用方法比較了instances

查看hashCodeequals方法這些鏈接瞭解詳情: -

+0

toString()的默認impl可能應該使用默認的hashCode(System.identityHashCode()) – irreputable

+0

@irreputable。由於'toString'方法中的當前實例是OP的類,並且他已經重寫了'hashCode'方法,所以根據多態性,OP類中的'hashCode'將被調用。 –

相關問題