Object.clone will achieve this. If copying the value is not appropriate for the field then it cannot be
declared final. In this example, the buffer array is immutable for the life of the object, but it can't be
declared final because its value needs to be explicitly set in clone.
If the object that should not be shared between the clone and the original, is not an array, that object should
support copying in some way. That may mean that the object itself supports clone, or that it has a copy
constructor that allows a duplicate object to be created. For example, the String class does not support
clone but it does have a copy constructor that creates a new String with the same contents as the String
passed to the constructor. The issues when writing copy constructors are the same as those for writing
cloneyou must decide when a simple field copy is sufficient and when more specific action is required. One
advantage the copy constructor has is that it can deal with final fields in situations where clone cannot.
Sometimes making clone work correctly is not worth the trouble, and some classes should not support
clone. In such cases, you should define a clone method that throws CloneNotSupportedException
so that objects with bad state will never be created by an unsuspecting subclass that uses clone.
You can declare that all subclasses of a class must support clone properly by overriding your class's clone
method with one that drops the declaration of CloneNotSupportedException. Subclasses
implementing the clone method cannot throw CloneNotSupportedException, because methods in a
subclass cannot add an exception to a method. In the same way, if your class makes clone public, all
extended classes must also have public clone methods, because a subclass cannot make a method less
visible than it was in its superclass.
3.9.3. Shallow versus Deep Cloning
The default implementation of clone provides what is known as a shallow clone or copyit simply performs a
field by field copy. A deep clone would clone each object referred to by a field and each entry in an array.
This would apply recursively and so deep cloning an object would clone all of the objects reachable from that
object. In general, clone is overridden to perform a deeper clone whenever a shallow clone is not
appropriatesuch as in the IntegerStack example.
The object serialization mechanism (see page 549) allows you to write entire object graphs to a stream of
bytes and, using that generated stream of bytes, create an equivalent copy of the original object graphs.
Serialization can provide a way to make deeper copies than those provided by Object.clone.
Exercise 3.8: Make Vehicle and PassengerVehicle into Cloneable types. Which of the four
described attitudes should each class take toward cloning? Is the simple copying done by Object.clone
correct for the clone methods of these classes?
Exercise 3.9: Write a Garage class whose objects can hold up to some number of Vehicle objects in an
array. Make Garage a Cloneable type, and write a proper clone method for it. Write a Garage.main
method to test it.
Exercise 3.10: Make your LinkedList class (from the exercises in Chapter 2) Cloneable, with clone
returning a new list that refers to the same values as the original list, not clones of the values. In other words,
changes to one list should not affect the other list, but changes to the objects referenced by the list would be
visible in both lists.
3.10. Extending Classes: How and When
The ability to write extended classes is a large part of the benefits of object-oriented programming. When you
extend a class to add new functionality, you create what is commonly termed an IsA relationshipthe extension