2010-01-15 80 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意味着您在执行路径中有无限递归。