|
Cloning objects
The most likely reason for making a local copy of an object is if you’re going to modify that object and you don’t want to modify the caller’s object. If you decide that you want to make a local copy, one approach is to use the clone( ) method to perform the operation. This is a method that’s defined as protected in the base class Object, and that you must override as public in any derived classes that you want to clone. For example, the standard library class ArrayList overrides clone( ), so we can call clone( ) for ArrayList:
//: appendixa:Cloning.java
// The clone() operation works for only a few
// items in the standard Java library.
import com.bruceeckel.simpletest.*;
import java.util.*;
class Int {
private int i;
public Int(int ii) { i = ii; }
public void increment() { i++; }
public String toString() { return Integer.toString(i); }
}
public class Cloning {
private static Test monitor = new Test();
public static void main(String[] args) {
ArrayList v = new ArrayList();
for(int i = 0; i < 10; i++ )
v.add(new Int(i));
System.out.println("v: " + v);
ArrayList v2 = (ArrayList)v.clone();
// Increment all v2's elements:
for(Iterator e = v2.iterator();
e.hasNext(); )
((Int)e.next()).increment();
// See if it changed v's elements:
System.out.println("v: " + v);
monitor.expect(new String[] {
"v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]",
"v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
});
}
} ///:~
The clone( ) method produces an Object, which must then be recast to the proper type. This example shows how ArrayList’s clone( ) method does not automatically try to clone each of the objects that the ArrayList contains—the old ArrayList and the cloned ArrayList are aliased to the same objects. This is often called a shallow copy, since it’s copying only the “surface” portion of an object. The actual object consists of this “surface,” plus all the objects that the references are pointing to, plus all the objects those objects are pointing to, etc. This is often referred to as the “web of objects.” Copying the entire mess is called a deep copy.
You can see the effect of the shallow copy in the output, where the actions performed on v2 affect v:
v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Not trying to clone( ) the objects contained in the ArrayList is probably a fair assumption, because there’s no guarantee that those objects are cloneable.[117]
|
|