Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

The canonical object idiom

Defining a baseline set of functionality for objects

  • Print
  • Feedback

Page 4 of 5

  • Both objects have the same class.

  • Corresponding instance variables with primitive types are equivalent (as reported by ==).

  • Corresponding instance variables with reference types are either both null or semantically equivalent (as reported by equals()).


For a bit more help on deciding how you should define equals(), consider that any implementation of equals() should have the following properties:

  • For any object reference a, a.equals(null) should return false.

  • For any object reference value a, a.equals(a) should return true. (equals() is reflexive.)

  • For any object references a and b, a.equals(b) should return true if and only if b.equals(a) returns true. (equals() is symmetric.)

  • For any object references a, b, and c, if a.equals(b) returns true and b.equals(c) returns true, then a.equals(c) should return true. (equals() is transitive.)

  • For any object references a and b, multiple invocations of a.equals(b) consistently return true or consistently return false. (equals() is consistent.)


Alternative ways to implement the idiom

If you wish to disallow cloning of an object, you can simply choose not to implement Cloneable, unless a superclass already implements Cloneable. In that case, you'll need to override clone() and throw CloneNotSupportedException. If a superclass implementation of clone() has removed CloneNotSupportedException from its throws clause, you should either change that superclass or allow cloning in the subclass.

If you wish to disallow serialization, you can simply choose not to implement Serializable.

Note that defining finalize() is not part of this idiom. A finalizer is not appropriate in general cases, although under certain circumstances you may want to write a finalizer. For advice on writing finalizers, follow the link from the Resources section to a previous Design Techniques article on that subject.

Note also that defining toString() is missing from the list above. I left it out because I believe Object has a reasonable default implementation for this method. Object's toString() method returns a string composed of the name of the class, an "at" sign ("@"), and the unsigned hexadecimal representation of the hash code of the object. If you do override toString, you should return a string that "textually represents" the object. The returned result should be concise, informative, and easy to read.

One other thing missing from the canonical object idiom is a no-arg constructor. Any class that has a no-arg constructor and implements Serializable is a JavaBean. See the Resources section for a link to a discussion of when it is appropriate to make a class into a bean.

Idiom issues

To help spark some discussion on the Flexible Java Forum, a discussion forum devoted to Java design topics, I will throw out some of the issues that may present themselves with this idiom (see the Resources section for a link to the forum):

  • Is "canonical object" the best name?

  • Am I justified in excluding a requirement to override toString from my canonical object recipe?

  • Should I throw something besides InternalError from the catch clause that catches CloneNotSupportedException? My general advice (given in my "Designing with Exceptions" article) is that programs should throw only exceptions, never errors. Usually the VM throws the errors. But in this case, I have implemented Cloneable. Thus, if Object's clone() implementation throws CloneNotSupported, I think that may qualify as an internal error to me. Since this "internal error" will likely never happen, what I throw probably isunimportant. But I'd still feel better about throwing an exception rather than an error. Perhaps what we need is a java.lang.ThisWasntSupposedToEverHappenException.

  • I'm a bit concerned about promoting the catching of CloneNotSupportedException at all, because, as I described above, it does tie the hands of anyone wishing to disallow cloning in a subclass.

  • Of course, there is that nagging question of the no-arg constructor, which, if it is part of the canonical object idiom, would make every canonical object into a JavaBean. This question has its own forum topic; you can find a link to it in the Resources section.


Next month

In next month's Design Techniques I'll talk about composition, inheritance, and interfaces.

  • Print
  • Feedback

Resources
  • Bill Venners' next book is Flexible Java http://www.artima.com/flexiblejava/index.html
  • Bill Venners is currently riding his bike through various European countries. As he encounters Internet cafes, he'll be posting reports about his trip. Follow along at
    http://www.artima.com/bv/travel/bike98.html
  • The discussion forum devoted to the material presented in this article http://www.artima.com/flexiblejava/fjf/canonical/index.html
  • Links to all previous design techniques articles http://www.artima.com/designtechniques/index.html
  • Recommended books on Java design, including information by the Gamma, et al., Design Patterns book http://www.artima.com/designtechniques/booklist.html
  • A transcript of an e-mail debate between Bill Venners, Mark Johnson (JavaWorld's JavaBeans columnist) and Mark Balbe on whether or not all objects should be made into beans http://www.artima.com/flexiblejava/comments/beandebate.html
  • Source packet that contains the example code used in this article http://www.artima.com/flexiblejava/code.html
  • Object orientation FAQ http://www.cyberdyne-object-sys.com/oofaq/
  • 7237 Links on Object Orientation http://www.rhein-neckar.de/~cetus/software.html
  • The Object-Oriented Page http://www.well.com/user/ritchie/oo.html
  • Collection of information on OO approach http://arkhp1.kek.jp:80/managers/computing/activities/OO_CollectInfor/OO_CollectInfo.html
  • Design Patterns Home Page http://hillside.net/patterns/patterns.html
  • A Comparison of OOA and OOD Methods http://www.iconcomp.com/papers/comp/comp_1.html
  • Object-Oriented Analysis and Design MethodsA Comparative Review http://wwwis.cs.utwente.nl:8080/dmrg/OODOC/oodoc/oo.html
  • Patterns discussion FAQ http://gee.cs.oswego.edu/dl/pd-FAQ/pd-FAQ.html
  • Patterns in Java AWT http://mordor.cs.hut.fi/tik-76.278/group6/awtpat.html
  • Software Technology's Design Patterns Page http://www.sw-technologies.com/dpattern/
  • Previous Design Techniques articles http://www.javaworld.com/topicalindex/jw-ti-techniques.html