2010-01-15 2 views
2

, поэтому я не очень разбираюсь в переопределении hashCode, и у меня, похоже, есть бесконечная рекурсия, как-то происходит с методом hashCode.Java overriding hashCode() получает StackOverflowError

Вот мой сценарий, у меня есть класс DuplicateCache, который является объектом кэша, который проверяет наличие дубликатов объектов в нашей системе. У меня есть статический внутренний класс Duplicate, который представляет объекты Duplicate.

DuplicateCache поддерживает HashMap, чтобы отслеживать все его записи. Каждая запись состоит из объекта Duplicate в качестве ключа и объекта Long в качестве значения.

Выполняю все свои операции с использованием ключей объектов Duplicate, а когда я запускаю метод put в HashMap, в методе hashCode() объекта Duplicate появляется бесконечная рекурсия.

хэш-код() в двух экземплярах вызывает хэш-код другого класса мне пришлось отменить, так что я буду включать, что после

Без дальнейших церемоний, вот мой код для нарушившего Дублированный класса:

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 хэш-код():

@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() будет нарушен.

Может ли кто-нибудь объяснить мне, что мне не хватает в этом хэш-коде() переопределении? Я знаю, что должно быть что-то, что я делаю неправильно, чтобы создать такое поведение.

Вот трассировки стека из моего файла журнала:

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 ...> 

Кроме того, что след ссылается на собственный метод получить так Heres, что для вас:

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

истекают() представляет собой метод, который делает временное удаление старых записей в таблице Хеш-таблица - объект HashMap

Спасибо!

+1

Пожалуйста, включите трассировку стека или достаточно, чтобы получить эту идею. –

+1

Что такое DuplicateCache2? – Bozho

ответ

5

С StackOverflowError, это не важно, где трассировка стека заканчивается (это в основном случайным образом, и может быть совершенно не связаны с проблемой), но то, что повторяющиеся последовательности до того, что есть - и это следует отметить, что именно ваша проблема ,

Ваши методы hashCode() выглядят прекрасно, они не могут вызывать StackOverflowError.

+1

О, как глупо, спасибо за указание, что у меня есть рекурсивный вызов в этом методе put. – Rich

0

Опубликовать трассировку стека. Если вы получаете SO Exception, тогда вы, очевидно, получили ссылочный цикл в определениях объектов. Трассировка стека должна немедленно проявляться там.

0

В большинстве случаев StackOverflowError означает, что у вас есть бесконечная рекурсия в вашем пути выполнения.