TheCanonicalObjectIdiom 

HOME INDEX SEARCH GO  

 <<O>>  Difference Topic TheCanonicalObjectIdiom (r1.3 - 05 Jun 2002 - JimMoore)
Changed:
<
<

>
>


 <<O>>  Difference Topic TheCanonicalObjectIdiom (r1.2 - 05 Jun 2002 - ScottCurtis)
Changed:
<
<

>
>


 <<O>>  Difference Topic TheCanonicalObjectIdiom (r1.1 - 04 Jun 2002 - AlainRavet)
Added:
>
>

%META:TOPICINFO{author="AlainRavet" date="1023179222" format="1.0" version="1.1"}% %META:TOPICPARENT{name="AlainRavet"}% 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



View | Diffs | r1.3 | > | r1.2 | > | r1.1 | More

e d i t a t t a c h r e f - b y d i f f s
Ideas,requests,problems regarding this site? Send feedback.
Copyright @ 2000-2003 by the contribution authors. All material on this collaboration tool is the property of the contributing authors.

Revision r1.1 - 04 Jun 2002 - 08:27 GMT - AlainRavet
Revision r1.3 - 05 Jun 2002 - 17:42 GMT - JimMoore
Copyright © 2001 by the contributing authors. All material on this collaboration tool is the property of the contributing authors.
Ideas, requests, problems regarding this site? Send feedback.