|
Making a copy of
an object seems at first to be a straight forward task:
Simply copy the values of all the properties
into another instance of the same class.
But
what about the properties that are references to other objects?
Copies
of these reference values mean they will point to the same objects as
the first class.
But
maybe that is not what we want. Perhaps we want all the objects referenced
by the first object to be copied as well.
These
two types of object copies are called:
- shallow copy -
exact bit copy of all the attributes
- deep copy
- objects referenced by the original properties
are copied as well.
The
Object()
class that is inherited by all Java classes (implicitly) includes the
clone()
method that will make exact bit copies of all the properties.
However,
it is a protected method. So a given object
can not be cloned by instances of any classes outside the package (unless
they are subclasses of the object's class). See the lecture
page on visibility.
The
reason for this is so that the class designer can
specify exactly what kind of clones (e.g. shallow or deep) should
be made.
Java
requires classes that want to override the clone()
method,
to implement the cloneable interface. The
clone()
method
must be made public as well to override the
access restrictions.
From
Exploring Java come the following examples
of shallow and deep copies:
|
public class
Sheep implements Cloneable {
Hashtable flock = new Hashtable();
public
Object clone() {
try {
// This
clone() from Object makes a bitwise copy
// of the properties (here
just "flock")
return super.clone();
} catch (CloneNotSupportedException
e ) {
throw new Error("This should never
happen!");
}
}
public
void main(String [] args) {
Sheep one = new Sheep();
Sheep anotherOne = (Sheep)one.clone();
// anotherOne.flock
points at the same HashTable as
// one.flock.
}
}
|
|
DeepSheep.java
import java.util.Hashtable;
public class
DeepSheep implements Cloneable {
Hashtable flock = new Hashtable();
public
Object clone() {
try {
// Here
also make a bitwise copy first
DeepSheep copy = (DeepSheep)super.clone();
// But
also make a new HashTable that is also a
// copy of the original HashTable.
copy.flock
= (Hashtable)flock.clone();
return copy;
} catch (CloneNotSupportedException e ) {
throw new Error("This should never
happen!");
}
}
public
void main(String [] args) {
DeepSheep one = new DeepSheep();
DeepSheep anotherOne = (DeepSheep)one.clone();
// anotherOne.flock
now points to a new HashTable in
// a different part of memory than one.flock
and is
// a copy of one.flock.
}
}
|
|