IntelliJ Community . TheCanonicalObjectIdiom

 
TheCanonicalObjectIdiom 

HOME INDEX SEARCH CHANGES GO  
references :

What's the idea ?

Have your objects provide the standard set of services (methods), that Object provides.

Why bother to override equals() and hashCode() in your classes ?

Example - the Name class you just wrote :

        Name name      =  new Name ("John", "Doe"),
             sameName =  new Name ("John", "Doe");

If you decide that name and sameName both represent a single 'thing', the following tests should pass :

        assertEquals ( "/1-1", name             , sameName ); 
        assertEquals ( "/1-2", name.hashCode()  , sameName.hashCode() );
        assertEquals ( "/1-3", name.toString()  , sameName.toString() );

Problem : by default, they all fail.
=> you must override equals(), hashCode(), and toString().

Overriding equals() :

    public boolean equals (Object o)
    {
        if (this == o)                    return true  ;
        if (! (o instanceof Name ))  return false ;
        final Name obj = (Name) o;
        return
                   obj.__firstName  .equals(  this.__firstName )
                && obj.__lastName   .equals(  this.__lastName )
          ;
    }
(code generated by the CanonicizerDoclet)

Overriding hashCode() :

The stupid way
(not recommended; but it works !) :

    public int hashCode ()    {
        return 1  ;
    }

The smart way

    public int hashCode ()
    {
        int result = 17;
        result   = 37 * result + __firstName.hashCode() ;
        result   = 37 * result + __lastName.hashCode() ;
        return result  ;
    }
(code generated by the CanonicizerDoclet) (recipe from Effective Java)

If you override equals(), but not hashCode(), you can get some nasty surprises :

        Set  s = new HashSet();
        s.add(name);
        s.add(sameName);

        assertEquals ( "FATAL ERROR : object added twice to the set" , 1 , s.size() ); <-- fail !

Java collections use equals() and hashCode() to store/retrieve objects => they must be consistent.

Overriding toString() :

toString() is used mostly for debugging => write it for human eyes.

    public String toString ()    {
        return "[Name: " + __firstName +  ","  +  __lastName +  "]"  ;
    }

name.toString() => "[Name: John, Smith]"

--AlainRavet


e d i t a t t a c h r e f - b y d i f f s m o r e
Have ideas, requests, problems regarding this site? Send feedback.
Copyright © 2000-2003 by the contributing authors. All materials at intellij.org are the property of the contributing authors.