Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
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
Page 3 of 5
It turns out that, so long as you implement Cloneable, Object's implementation of clone() will never throw CloneNotSupportedException. Object's implementation of clone() checks to see if the object's class implements Cloneable; if it does, it clones the object by making a direct field-by-field copy of the original in the clone. Only if the object's
class doesn't implement Cloneable will Object's implementation of clone() throw CloneNotSupportedException. So if you implement Cloneable, you may as well catch CloneNotSupportedException just to keep it out of your clone()'s throws clause.
The one risk to heeding this advice is that when you remove CloneNotSupportedException from your clone()'s throws clause, you tie the hands of anyone who ever wants to disallow cloning in a subclass of your class. The customary way to
disallow cloning in a subclass of some class that allows and supports cloning is to override clone() and throw CloneNotSupportedException. Thus, you should consider whether you want to enable subclasses to disallow cloning when you implement clone().
My opinion is that if you are not sure, you should catch CloneNotSupportedException, which effectively sets the policy that all subclasses will be clonable. I believe situations in which someone will want
to disallow cloning in a subclass will be rare. Therefore, the ease of use you gain by not forcing clients to deal with CloneNotSupportedException outweighs the slight risk that you will be frustrating someone who wants to disallow cloning in a subclass at some point
in the future.
Don't support cloning in immutable objects
If the object is immutable, you don't need to (and shouldn't) make it clonable. The reason you clone an object is so that
the two instances can evolve independently thereafter. For example, you may clone an object before passing it to a method
that alters the object. Because immutable objects can't evolve (their state doesn't ever change), there is no need to clone
them. Everyone can safely share the same immutable instance.
Make equals() do a semantic compare
An important aspect of the canonical object idiom is implementing equals() such that it does a semantic comparison. Canonical objects override equals(), because the default implementation of equals() in class Object just returns true if one object '==' the other object. In other words, comparing two objects with equals() yields the same result, by default, as comparing to objects with Java's == operator. Why are there two ways to check objects for equality? Because they are supposed to be different.
Java's == operator simply checks to see if two references refer to the same object exactly. Invoking equals() on an object is supposed to do a semantic compare: if the two objects "mean the same thing," equals() should return true.
What does it mean for an object to "mean the same thing" as another object? Well, that's what you, as designer of a class, get to decide. In general, however, two objects are semantically equal when they have the same class and their states are equal. In other words, semantic equality means that: