Why people are so afraid of using clone() (on collection and JDK classes)?
So, give me a reason why not to use clone() with JDK classes?
- Given an
ArrayList
reference, you would need agetClass
check to check that it is not a subclass of the JDK class. And then what? Potential subclasses cannot be trusted. Presumably a subclass would have different behaviour in some way. - It requires that the reference is more specific than
List
. Some people don't mind that, but the majority opinion is that that is a bad idea. - You'll have to deal with a cast, an unsafe cast at that.
From my experience, the problem of clone() arises on derived classes.
Say, ArrayList
implements clone(), which returns an object of ArrayList
.
Assume ArrayList
has an derived class, namely, MyArrayList
. It will be a disaster if MyArrayList
does not override the clone() method. (By default it inherits the code from ArrayList
).
The user of MyArrayList
may expect clone() to return an object of MyArrayList
; however, this is not true.
This is annoying: if a base class implements clone(), its derived class has to override the clone() all the way.
I will answer with a quote from the man himself (Josh Bloch on Design - Copy Constructor versus Cloning):
There are very few things for which I use
Cloneable
anymore. I often provide apublic clone
method on concrete classes because people expect it.
It can't be any more explicit than this: clone()
on his Collection Framework classes are provided because people expect it. If people stop expecting it, he would've gladly thrown it away. One way to get people to stop expecting it is to educate people to stop using it, and not to advocate its use.
Of course, Bloch himself also said (not exact quote but close) "API is like sex: make one mistake and you support it for life". Any public clone()
can probably never be taken back. Nevertheless, that's not a good enough reason to use it.
In order not to encourage other, less experienced, developers to implement Clone()
themselves. I've worked with many developers whose coding styles are largely copied from (sometimes awful) code that they've worked with.
It does not enforce whether the implementer will do a deep or shallow copy.