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

What am I missing? Is there a recurrent call to hashCode() method because of default toString() method?

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
Joe
  • 7,749
  • 19
  • 60
  • 110
  • @Rohit Jain's answer explains the stack overflow. But I would recommend against generating a string just to get the hash code. In this case, why not just use `collarID ^ String.valueOf(name).hashCode()`? – Dilum Ranatunga Oct 26 '12 at 16:41
  • It is a question I did wrong in a mock exam – Joe Oct 26 '12 at 16:43
  • I see. This must have been a nasty surprise, then. For future reference, it's good rule of thumb to assume that Java tries to make the default implementation say unequal until you say otherwise. This leads to less unexpected behavior. To that end, instances of classes that don't define `toString`, `equals`, `hashCode` will show different string, hashcodes and say they are unequal. – Dilum Ranatunga Oct 26 '12 at 16:47

1 Answers1

11

If you see the source code of toString method of Object class, it looks like: -

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

So, it internally invokes hashCode() method. Now, since you have overrided the hashCode method, it will invoke the hashCode method of your class, which agains invokes toString method of Object class.

This will certainly result in StackOverFlowError

You can rather override the toString method in your class, to make it work.

P.S.: -

However, your hashCode implementation should be designed, considering the attributes you have used in equals method, to maintain the contract between hashCode and equals method. Use only those attributes in calculating hashCode that you have used to compare your instances in equals method.

See these links for more details on hashCode and equals method:-

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • the default impl of toString() should probably use the default hashCode instead (System.identityHashCode()) – irreputable Oct 26 '12 at 17:33
  • @irreputable. Since the current instance inside the `toString` method is of the OP's class, and he has overrided the `hashCode` method, so according to polymorphism, the `hashCode` in OP's class will be invoked. – Rohit Jain Oct 26 '12 at 17:35