Sponsored Link •
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
Cloneable. In that case, you'll need to
clone() and throw
CloneNotSupportedException. If a superclass
clone() has removed
CloneNotSupportedException from its
clause, you should either change that superclass or allow cloning in
If you wish to disallow serialization, you can simply choose not to
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
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.
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
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.
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):
toStringfrom my canonical object recipe?
InternalErrorfrom 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
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
CloneNotSupportedExceptionat all, because, as I described above, it does tie the hands of anyone wishing to disallow cloning in a subclass.
In next month's Design Techniques I'll talk about composition and inheritance.
A request for reader participation
I encourage your comments, criticisms, suggestions, flames -- all kinds of feedback -- about the material presented in this column. If you disagree with something, or have something to add, please let me know.
About the author
Bill Venners has been writing software professionally for 12 years. Based in Silicon Valley, he provides software consulting and training services under the name Artima Software Company. Over the years he has developed software for the consumer electronics, education, semiconductor, and life insurance industries. He has programmed in many languages on many platforms: assembly language on various microprocessors, C on Unix, C++ on Windows, Java on the Web. He is author of the book: Inside the Java Virtual Machine, published by McGraw-Hill. Reach Bill at email@example.com.
This article was first published under the name The Canonical Object Idiom in JavaWorld, a division of Web Publishing, Inc., September 1998.