Item 11: Override clone judiciously

1.  The Cloneable interface was intended as a mixin interface for objects to advertise that they permit cloning. However it lacks a clone method, and Object’s clone method is protected.

 

2.  If a class implements Cloneable, Object’s clone method returns a field-by-field copy of the object; otherwise it throws CloneNotSupportedException.

 

3.  Java specification requires that cloning an object will typically entail creating a new instance of its class, but it may require copying of internal data structures as well. No constructors are called.

 

4.  In practice, programmers assume that if they extend a class and invoke super.clone from the subclass, the returned object will be an instance of the subclass. If you override the clone method in a non-final class, you should return an object obtained by invoking super.clone. If all of a class’s superclasses obey this rule, then invoking super.clone will eventually invoke Object’s clone method, creating an instance of the right class.

 

5.  In practice, a class that implements Cloneable is expected to provide a properly functioning public clone method.

 

6.  The fields declared in your class (if any) will have values identical to those of the object being cloned by super.clone() if all the clone methods of super classes behave well. If every field contains a primitive value or a reference to an immutable object, the returned object may be exactly what you need.

 

7.  Because Object.clone returns Object, you must cast the result of super.clone() before returning it.

 

8.  In effect, the clone method functions as another constructor; you must ensure that it does no harm to the original object and that it properly establishes invariants on the clone.

 

9.  Calling clone on an array returns an array whose compile-time type is the same as that of the array being cloned. (instead of Object)

 

10.  The clone architecture is incompatible with normal use of final fields referring to mutable objects.

 

11.  Like a constructor, a clone method should not invoke any non-final methods on the clone under construction. If clone invokes an overridden method, this method will execute before the subclass in which it is defined has had a chance to fix its state in the clone, quite possibly leading to corruption in the clone and the original.


12.  Public clone methods should omit the CloneNotSupportedException because methods that don’t throw checked exceptions are easier to use.

 

13.  If a class that is designed for inheritance, the overriding clone method should mimic the behavior of Object.clone: it should be declared protected, it should be declared to throw CloneNotSupportedException, and the class should not implement Cloneable. This gives subclasses the freedom to implement Cloneable or not, just as if they extended Object directly.

 

14.  To recap, all classes that implement Cloneable should override clone with a public method whose return type is the class itself. This method should first call super.clone and then fix any fields that need to be fixed. Typically, this means copying any mutable objects that comprise the internal “deep structure” of the object being cloned, and replacing the clone’s references to these objects with references to the copies. While these internal copies can generally be made by calling clone recursively, this is not always the best approach. If the class contains only primitive fields or references to immutable objects, then it is probably the case that no fields need to be fixed. There are exceptions to this rule. For example, a field representing a serial number or other unique ID or a field representing the object’s creation time will need to be fixed, even if it is primitive or immutable.

 

15.  A fine approach to object copying is to provide a copy constructor or copy factory. A copy constructor is simply a constructor that takes a single argument whose type is the class containing the constructor. A copy factory is the static factory analog of a copy constructor.

 

16.  The copy constructor approach and its static factory variant have many advantages over Cloneable/clone: they don’t rely on a risk-prone extralinguistic object creation mechanism; they don’t demand unenforceable adherence to thinly documented conventions; they don’t conflict with the proper use of final fields; they don’t throw unnecessary checked exceptions; and they don’t require casts.

 

17.  A copy constructor or factory can take an argument whose type is an interface implemented by the class. For example, by convention all general purpose collection implementations provide a constructor whose argument is of type Collection or Map. Interface-based copy constructors and factories, more properly known as conversion constructors and conversion factories, allow the client to choose the implementation type of the copy rather than forcing the client to accept the implementation type of the original.

你可能感兴趣的:(Effective Java,clone,Cloneable,copy factory)