2010-01-15 83 views
2

所以我不熟悉重寫hashCode,我似乎有一些無限遞歸以某種方式進行與hashCode方法。Java重寫hashCode()得到StackOverflowError

這是我的場景,我有一個DuplicateCache類,它是一個緩存對象,用於檢查我們系統中的重複對象。我有一個代表重複對象的靜態內部類Duplicate。

DuplicateCache保持一個HashMap來跟蹤其所有條目。每個條目由作爲鍵的重複對象和作爲值的長對象組成。

我正在執行所有使用重複對象鍵的操作,並且當我將put方法運行到HashMap中時,Duplicate對象的hashCode()方法中會出現無限遞歸。

的hashCode()方法中重複的方法調用另一個類,我不得不重寫的哈希代碼,所以我會包括後

事不宜遲,這裏是我的問題的重複類代碼:

public static class Duplicate{ 
    private String merchId; 
    private String custId; 
    private MagicPrice price; 
    private int status; 
    private boolean compareStatus; 

// snip methods   

    @Override public boolean equals(Object o){ 
     cat.debug("In the override equals method of Duplicate"); //DELETEME 

     if(o instanceof Duplicate) 
      return equals((Duplicate) o); 
     else 
      return false; 
    } 

    @Override public int hashCode() { 
     return merchId.hashCode() + custId.hashCode() + price.hashCode(); 
    } 


    /*Equals method vital to the HashMap cache operations 

    How the compareStatus and status fields change this: 
    if both objects have true for compareStatus -> Equals will compare the statuses 
    otherwise         -> Equals will not compare the statuses 

    If we only want to do an in_progress check, we need to compare status. 
    On the other hand success checks need to ignore the status. 
    */ 
    public boolean equals(Duplicate d){   
     try{ 
      if(merchId.equals(d.merchId) && custId.equals(d.custId) && (price.compareTo(d.price)==0)){ 
       if(this.compareStatus && d.compareStatus && this.status != d.status) 
        return false; 

       return true; 
      } 
     }catch(PriceException pe){ 
      //Catching from MagicPrice.compareTo object method, return false 
      return false; 
     } 

     return false; 
    }   
} 

這會爲複製對象,現在MagicPrice hashcode()方法:

@Override public boolean equals(Object o){ 
    if(!(o instanceof MagicPrice)) 
     return false; 

    MagicPrice p = (MagicPrice)o; 

    if(this.iso4217code.equals(p.iso4217code) && this.value.equals(p.value)) 
     return true; 

    else return false; 
} 

@Override public int hashCode(){ 
    return value.hashCode() + this.iso4217code.hashCode(); 
} 

在這個類的值字段是一個BigDecimal和ISO4217代碼是一個字符串。爲什麼它的價值stackTrace最終死於BigDecimal hashCode()方法,但我不相信BigDecimal hashCode()方法會被破壞。

有人請向我解釋什麼我失蹤這個hashCode()覆蓋?我知道必須有一些我做錯了產生這種行爲。

這是從我的日誌文件中的堆棧跟蹤:

java.lang.StackOverflowError 
    at java.math.BigDecimal.hashCode(BigDecimal.java:2674) 
    at com.moremagic.util.MagicPrice.hashCode(Unknown Source) 
    at com.moremagic.core.DuplicateCache2$Duplicate.hashCode(Unknown Source) 
    at java.util.HashMap.get(HashMap.java:300) 
    at com.moremagic.util.ExpirableHashMap.get(Unknown Source) 
    at com.moremagic.core.DuplicateCache2.put(Unknown Source) 
    at com.moremagic.core.DuplicateCache2.put(Unknown Source) 
    at com.moremagic.core.DuplicateCache2.put(Unknown Source) 
    at com.moremagic.core.DuplicateCache2.put(Unknown Source) 
    <... and it continues with the put references for a looong time ...> 

也是跟蹤引用專有get方法使繼承人爲你:

public Object get(Object key) { 
expire(); 
return hashtable.get(key); 
} 

到期()是確實的方法基於時間去除表中的舊條目 散列表是HashMap對象

謝謝!

+1

請包括堆棧跟蹤,或足夠的它來得到的想法。 – 2010-01-15 19:27:29

+1

什麼是DuplicateCache2? – Bozho 2010-01-15 19:38:15

回答

5

對於StackOverflowError,堆棧跟蹤結束的位置並不重要(這基本上是隨機的,可能與問題完全無關),但是之前的重複序列是什麼 - 並且應該明確指出您的問題是什麼。

你的hashCode()方法看起來不錯,他們不應該能夠導致StackOverflowError

+1

哦,多麼愚蠢,謝謝你指出,我有一個遞歸調用該put方法.. – Rich 2010-01-15 19:37:15

0

發佈堆棧跟蹤。如果你得到了一個SO異常,那麼你顯然在對象定義的某個地方有了一個引用循環。堆棧跟蹤應該立即顯示在哪裏。

0

在大多數情況下,StackOverflowError意味着您在執行路徑中有無限遞歸。