Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why people are so afraid of using clone() (on collection and JDK classes)?

Tags:

java

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?

like image 352
Bozho Avatar asked Apr 08 '10 06:04

Bozho


People also ask

Why is clone () method used in Java?

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.

Why we use clone ()? What is the purpose?

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.

Why is Java clone broken?

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.

Should I use Java clone?

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.


4 Answers

So, give me a reason why not to use clone() with JDK classes?

  • Given an 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.
  • 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.
like image 118
Tom Hawtin - tackline Avatar answered Oct 20 '22 14:10

Tom Hawtin - tackline


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.

like image 38
SiLent SoNG Avatar answered Oct 20 '22 15:10

SiLent SoNG


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 a public 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.

like image 39
polygenelubricants Avatar answered Oct 20 '22 14:10

polygenelubricants


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.

like image 35
Daniel Avatar answered Oct 20 '22 14:10

Daniel