Java Reference
In-Depth Information
PITFALL: The
clone
Method Is Protected in
Object
★
When defining the copy constructor and
clone
method for our generic linked list
(Display 15.12), we would have liked to have cloned the data in the list being copied.
We would have liked to change the code in the helping method
copyOf
by adding
invocations of the
clone
method as follows:
newHead =
new
Node((T)(position.data).clone( ),
null
);
end = newHead;
position = position.link;
while
(position !=
null
)
{
//copy node at position to end of new list.
end.link =
new
Node((T)(position.data).clone( ),
null
);
end = end.link;
position = position.link;
}
This code is identical to code in
copyOf
except for the addition of the invocations
of
clone
shown in red and the type casts shown in red. (The type casts are needed
because Java thinks
clone
returns a value of type
Object
.)
If this modified code (with the
clone
method) would compile (and if the type
plugged in for
T
has a well-defined
clone
method that makes a deep copy), then this
modified code would produce a truly independent linked list with no references in
common with the list being copied. Unfortunately, this code will not compile.
If you try to compile this code, you will get an error message saying that the
method
clone
is protected in the class
Object
. True, we used the type
T
, not the type
Object
, but any class can be plugged in for
T
. So when the generic linked list is com-
piled, all Java knows about the type
T
is that it is a descendent class of
Object
. Since
the designers of the
Object
class chose to make the method
clone
protected, you sim-
ply cannot use the
clone
method in the definition of methods such as
copyOf
.
Why was the
clone
method labeled
protected
in
Object
? Apparently for security
reasons. If a class could use the
clone
method unchanged from
Object
, then that
would open the possibility of copying sections of memory unchanged and unchecked
and so might give unauthorized memory access. The problem is made more serious by
the fact that Java is used to run programs on other machines across the Internet.
The way Java defines the
clone
method in
Object
and the way it specifies how
clone
should be defined in other classes is controversial. Do not be surprised if some
future version of Java handles the
clone
method differently. But for now, you are stuck
with these
clone
problems.
In many situations, the version of
copyOf
in Display 15.12 (without the use of
clone
) is good enough, but there is a way to get a true deep copy. One way to get a
deep copy is to somehow restrict the type
T
to classes that do have a public
clone
method that makes a deep copy. Something like this can be done and is discussed in
the Programming Tip “Use a Type Parameter Bound for a Better
clone
.”
■