In a Java application, even if a class implements Cloneable interface, we can not make a clone of the class. This itself says a lot about broken behavior of cloning in Java. In this post, I will explore other reasons for saying so.
In cloning in Java, we discussed the various ways of creating clone of Java objects including shallow and deep cloning, copy constructors and some best practices. Now let’s discuss about Cloneable
interace gaps.
Table of contents How Cloneable interface is braken? What expert says Java copy best practices
How Java Cloneable interface is braken?
- The very first gap is that clone() method should have been in Cloneable interface. If you implement Cloneable interface(don’t override clone() method) then it does not affect a single thing in your class on runtime. In fact, the default behavior should have been if Class A implements Cloneable then someone should be able to do this:
//Ideal behavior; Cloneable should have been implemented like this class A implements Cloneable { //member attributes and methods } class B { A a = new A(); if(a instanceof Cloneable) { A copied = a.clone(); //I should be able to do this; But I am not. } }
- clone() method does not call any constructor for creating the new instance, which makes it another variant of constructor with behavior not in our control. In other words: “Cloning invokes an extralinguistic way of constructing objects – i.e. without constructors“.
- Apart from above facts, it is also a classic example of spelling mistakes. The correct spelling should have been “Clonable“.
- There is no mechanism in java to create deep copies. Even calling super.clone() till the Object class, creates shallow copy.
What experts say about Java Cloneable interface
Josh Block in an interview
“There are a few design flaws, the biggest of which is that the Cloneable interface does not have a clone method. And that means it simply doesn’t work: making something Cloneable doesn’t say anything about what you can do with it. Instead, it says something about what it can do internally. It says that if by calling super.clone repeatedly it ends up calling Object’s clone method, this method will return a field copy of the original.”
Ken Arnold in an inteview
“If I were to be God at this point, and many people are probably glad I am not, I would say deprecate Cloneable and have a Copyable, because Cloneable has problems. Besides the fact that it’s misspelled, Cloneable doesn’t contain the clone method. That means you can’t test if something is an instance of Cloneable, cast it to Cloneable, and invoke clone. You have to use reflection again, which is awful. That is only one problem, but one I’d certainly solve.”
Java copy best practices
As discussed in my previous post, use factory methods when you need to have a copy of an object. It has following benefits:
- You can return an instance of different class also if needed. For example, If someone wants to copy a
LinkedList
, if needed you can return anArrayList
also. - You can choose whether you need to make deep or shallow copy.
- You can decide which members needs to be copied and which not.
- Different methods can have different names clearly pointing their responsibilities.
I hope this post shed some light on broken behavior of Java Cloneable interface (marker interface) and best practices while creating copy of an Object in Java.
Happy Learning !!