Lately I’ve been learning Effective Java by Joshua Block. Have been mesmerized by the powerful ideas on using Java language. Thus, I have decided that I needed to write a blog series regarding the items (as Joshua puts it out). There are altogether 78 items (Hoping to learn one item every day) and hopefully I will also have an equivalent number of blog post. This is the 11th post of the series, enjoi reading. To go to 10th post.
Methods Common to All Objects
Item 11
Override clone judiciously
What is clone() method?
- Creates and returns a copy of this object.
- The precise meaning of “copy” may depend on the class of the object.
What is the contract for clone() method ?
- The general contract is that, for any object
x
, the expression:
(i) x.clone() != x // Will be true(ii) x.clone().getClass() == x.getClass() // will be true, but these are not absolute requirements. (iii) x.clone().equals(x) // will be true, this is not an absolute requirement.No constructors are called.
Why clone contract is weak?
- The provision that “No constructors are called” is too strong. If the class is final, clone can even return an object created by a constructor.
- In effect, the clone method functions as another constructor; hence, we must ensure that it does no harm to the original object.
- The second provision is weak. If a clone method returns an object from a non-final class created by a constructor, it will have a wrong class.
- The clone() method should always return an object returned by invoking super.clone from all of it’s subclass.
How do we implement clone() ?
- By implementing Cloneable interface, which indicates to the Object.clone() method that is is legal for that method to make a field-for-field copy of instances of that class.
- But, the primary flaw is that it lacks a clone method and Object’s clone method is protected.
What does Cloneable interface do?
- Given that it contains no methods, it determines the behavior of Object’s protected clone implementation.
- If a class implements Cloneable, Object’s clone method returns a clone (field-by-field copy) ; otherwise it throws CloneNotSupportedException.
Why Cloneable is flawed?
- The primary flaw is that it lacks clone method and Object’s clone method is protected.
- We cannot invoke clone method on an object merely because it implements cloneable.
- The only way to invoke clone method is via reflection.
- In practice, a class that implements Cloneable is expected to provide a properly functioning public clone method.
- The clone architecture is incompatible with normal use of final fields referring to mutable objects, except in cases where the mutable objects may be safely shared between an object and it’s clone.
TL:DR
You are better off providing an alternative means of object copying or simply not providing the capability.
A fine approach to object copying is to provide a copy constructor or copy factory.
To go to 12th item in the series
To learn more:
- To listen to podcast: fragmentedpodcast.com
- The source book: Effective Java 2nd edition