Java Reference
In-Depth Information
Programming Tip:
When bounding generic types, use an interface that declares a pub-
lic method
clone
instead of using
Cloneable
. The new interface must extend
Cloneable
,
however.
30.21
Using
Copyable
as a bound for
T
requires us to change the implementation of
AList
's constructor.
Recall from Listing 13-1 in Chapter 13 that one field of
AList
is an array of list entries:
private
T[] list;
Writing
list = (T[])
new
Object[initialCapacity];
in the constructor causes a
ClassCastException
. Instead, we write
list = (T[])
new
Copyable[initialCapacity];
30.22
Now we can implement
clone
. We will invoke
super.clone()
within a
try
block but perform the
rest of the tasks after the
catch
block. Thus, we have the following outline for
AList
's method
clone
:
public
Object clone()
{
AList<T> theCopy =
null
;
try
{
theCopy = (AList<T>)
super
.clone();
// not enough by itself
}
catch
(CloneNotSupportedException e)
{
throw new
Error(e.toString());
}
< For a deep copy, we need to do more here, as you will see. >
. . .
return
theCopy;
}
// end clone
The method first invokes
super.clone
and casts the returned object to
AList<T>
. To perform a
deep copy, we need to clone the data fields that are or could be mutable objects. Thus, we need to
clone the array
list
.
30.23
Arrays in Java have a public
clone
method; in other words, they implement
Cloneable
. So we can
add the following statement to the list's
clone
method:
theCopy.list = (T[])list.clone();
No
try
and
catch
blocks are necessary here.
An array's
clone
method creates a shallow copy of each object in the array. For our deep copy,
we need to clone each array entry. Since we insisted that the list's entries have a public
clone
method, we can write a loop whose body contains the following statement:
theCopy.list[index] = (T)list[index].clone();
We can control the loop by using
AList
's data field
numberOfEntries
, which records the number of
entries in the list.
Thus, we have the following definition of
clone
for the class
AList
:
public
Object clone()
{
AList<T> theCopy =
null
;