This is raised because of the technical difficulties faced in my Project.
Problem: I need to clone a Object of a Class where it extended the properties(Inheritance) from a third party library class(where we don't have access to modify its contents)
Let me explain with example below:
Parent Class:
public class UnChangeableBaseClass {
//fields and Methods
}
Child Class:
class DerivedLocalClass extends UnChangeableBaseClass implements Cloneable {
// local fields and methods
public Object clone(){
Object clonedObj= null;
try{
clonedObj = super.clone();
}
catch(CloneNotSupportedException e){
//log exceptions
}
}
}
When I try to do this, super.clone()
method refers to Class - UnChangeableBaseClass
Type and it doesn't overrides the Object clone()
methods. I believe all classes were extended with java.lang.Object class
, implicitly protected Object clone()
method would be inherited to this Parent Class. So, i thought in such a way that this method in Derived Class would overrides the Parent/Object clone method. But during runtime JVM search for the clone method explicitly defined in UnChangeableBaseClass
. Hope I explained in proper way without confusing you.
My questions are follows:
How can I implement clone method in this typical case, where we cannot add any method
in parent class to havesuper.clone()
to call Object clone method.If above case is not possible, is there any other way to clone the Derived Class
Object (by considering all the limitations in above scenario)Finally, just to know the reason for this JVM behaviour (described above).
JVM Cloning works by making use of the Marker interface Cloneable rather than looking for Object.clone(). It is true that all the Java Classes will inherit clone method but according to javadoc for Cloneable
In your case you can't do super.clone() because it is not marked to be Cloneable. If you cannot change the parent class then you will have to make a Copy of it yourself.
Correct Method signature is below
Clone is
Protected
method inObject
class so it is accessible to you inside class, and if you are extending from it.super.clone()
is just needed to callclone()
method from object which calls methodinternalClone
onthis
which is current class object.So above
clone()
method insideObject
will only throwCloneNotSupportedException
if instance on which it is called is notCloneable
I see some misconceptions about clone method
clone()
method isprotected
insideObject
class so you can not callclone()
outside of class. e.g.child.clone()
unless you override it and make accesspublic
Cloneable
is marker interface and if you do not mark classCloneable
then you will getCloneNotSupportedException
if you callclone()
methodsuper.clone
need to be modified.super.clone
. If a class and all of itssuperclasses (except Object)
obey this convention, it will be the case thatx.clone().getClass() == x.getClass()
.So below code works fine
References :
I am using java 1.7 and I don't get any problem in running the code given by OP. Unless the superclass has overridden clone to throw an exception I think this should work even if the superclass does not declare itself clonable.
I will note that
is not overriding the clone method, its missing the throws clause.
Well, since
clone
method is a protected method inObject
class, so it is accessible in your super classUnChangeableBaseClass
also, since it extends fromObject
class. So, basically you can access theclone
method, usingsuper.clone()
, from your base classDerivedLocalClass
.I would suggest, even though you have the option to use
clone
method to clone the object, you should not use it. It would be better to use acopy-constructor
in your derived class, and add asuper()
call to the base class constructor.Also, see
Effective Java - Item#11 - Override clone judiciously
, which suggest thatclone
method is broken.In this article: -
Josh Bloch on Design - Copy Constructor versus Cloning
, you would like to see the very first paragraph ofBloch
: -So, conclusion is that, you can have a
copy constructor
in yourDerivedLocalClass
, which will return you the copy of the invoking object, something like this: -