A number of times I've argued that using clone()
isn't such a bad practice. Yes, I know the arguments. Bloch said it's bad. He indeed did, but he said that implementing clone()
is bad. Using clone on the other hand, especially if it is implemented correctly by a trusted library, such as the JDK, is OK.
Just yesterday I had a discussion about an answer of mine that merely suggests that using clone()
for ArrayList
is OK (and got no upvotes for that reason, I guess).
If we look at the @author
of ArrayList
, we can see a familiar name - Josh Bloch. So clone()
on ArrayList
(and other collections) is perfectly fine (just look at their implementations).
Same goes for Calendar
and perhaps most of the java.lang
and java.util
classes.
So, give me a reason why not to use clone()
with JDK classes?
Clone() method in Java. Object cloning refers to the creation of an exact copy of an object. It creates a new instance of the class of the current object and initializes all its fields with exactly the contents of the corresponding fields of this object. In Java, there is no operator to create a copy of an object.
The clone() method is used to create a copy of an object of a class which implements Cloneable interface. By default, it does field-by-field copy as the Object class doesn't have any idea about the members of the particular class whose objects call this method.
clone() are "broken" in the sense that they have design flaws and are difficult to use correctly. However, clone() is still the best way to copy arrays, and cloning has some limited usefulness to make copies of instances of classes that are carefully implemented.
Java Practices->Avoid clone. Avoid implementing clone . If you need to extend a superclass that implements clone , then your subclass must implement clone as well. The quickest solution is for your subclass to simply throw an exception.
So, give me a reason why not to use clone() with JDK classes?
ArrayList
reference, you would need a getClass
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.List
. Some people don't mind that, but the majority opinion is that that is a bad idea.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With