The clone() is a tricky method from java.lang.Object class, which is used to exercise a re-create of an Object inward Java. The intention of the clone() method is simple, to render a cloning mechanism, merely somehow it's implementation became tricky as well as has been widely criticized from a long time. Anyway, nosotros volition non croak to classic fence of clone inward Java, at to the lowest degree for now; instead, nosotros volition attempt to larn how clone method industrial plant inward Java. To live fair, understating cloning machinery inward Java is non slow as well as fifty-fifty experienced Java programmer neglect to explicate how cloning of mutable object works, or a difference betwixt deep as well as shallow re-create inward Java.
In this three-part article, nosotros volition start run across working of clone method inward Java, as well as inward mo business office nosotros volition larn how to override clone method inward Java, as well as lastly nosotros volition hash out deep re-create vs shallow copy mechanism.
The argue I chose to brand this a three-part article is to proceed the focus on i affair at a time. Since clone() itself is confusing enough, it's best to sympathise concept i yesteryear one. In this post, nosotros volition larn what is clone method, what it does as well as How clone method industrial plant inward Java.
By the way, clone() is i of the few telephone substitution methods defined yesteryear objects, others beingness equals, hashcode(), toString() along amongst hold off as well as notify methods.
In this three-part article, nosotros volition start run across working of clone method inward Java, as well as inward mo business office nosotros volition larn how to override clone method inward Java, as well as lastly nosotros volition hash out deep re-create vs shallow copy mechanism.
The argue I chose to brand this a three-part article is to proceed the focus on i affair at a time. Since clone() itself is confusing enough, it's best to sympathise concept i yesteryear one. In this post, nosotros volition larn what is clone method, what it does as well as How clone method industrial plant inward Java.
By the way, clone() is i of the few telephone substitution methods defined yesteryear objects, others beingness equals, hashcode(), toString() along amongst hold off as well as notify methods.
What is the clone of an object inward Java?
An object which is returned yesteryear the clone() method is known equally a clone of master copy instance. H5N1 clone object should follow basic characteristics e.g. a.clone() != a, which agency master copy as well as clone are 2 dissever object inward Java heap, a.clone().getClass() == a.getClass() as well as clone.equals(a), which agency clone is exact re-create of master copy object. This feature is followed yesteryear a good behaved, correctly overridden clone() method inward Java, merely it's non enforced yesteryear the cloning mechanism. Which means, an object returned yesteryear clone() method may violate whatever of these rules.
By next the convention of returning an object yesteryear calling super.clone(), when overriding clone() method, y'all tin give the axe ensure that it follows start 2 characteristics. In club to follow the tertiary characteristic, y'all must override equals method to enforce logical comparison, instead of physical comparing exists inward java.lang.Object.
For example, clone() method of Rectangle shape inward this method render object, which has these characteristics, merely if y'all run the same programme yesteryear commenting equals(), you will run across that tertiary invariant i.e. clone.equals(a) volition render false. By the way at that spot are a pair of proficient items on Effective Java regarding effective purpose of clone method, I highly recommend to read those items later going through this article.
By next the convention of returning an object yesteryear calling super.clone(), when overriding clone() method, y'all tin give the axe ensure that it follows start 2 characteristics. In club to follow the tertiary characteristic, y'all must override equals method to enforce logical comparison, instead of physical comparing exists inward java.lang.Object.
For example, clone() method of Rectangle shape inward this method render object, which has these characteristics, merely if y'all run the same programme yesteryear commenting equals(), you will run across that tertiary invariant i.e. clone.equals(a) volition render false. By the way at that spot are a pair of proficient items on Effective Java regarding effective purpose of clone method, I highly recommend to read those items later going through this article.
How Clone method industrial plant inward Java
protected as well as native in Object class, thence implemented inward native code. Since its convention to render clone() of an object yesteryear calling super.clone() method, whatever cloning procedure eventually reaches to java.lang.Object clone() method. This method, start checks if the corresponding object implements Cloneable interface, which is a marking interface. If that instance doesn't implement Cloneable thence it throws CloneNotSupportedException inward Java, a checked exception, which is e'er required to live handled patch cloning an object. If an object passes this check, than java.lang.Object's clone() method creates a shallow re-create of the object as well as returned it to the caller.
Since Object class' clone() method creates re-create yesteryear creating novel instance, as well as thence copying field-by-field, similar to assignment operator, it's fine for primitives as well as Immutable object, merely non suited if your shape contains roughly mutable information construction e.g. Collection classes like ArrayList or arrays. In that case, both master copy object as well as re-create of the object volition betoken to the same object inward the heap. You tin give the axe foreclose this yesteryear using the technique known equally deep cloning, on which each mutable champaign is cloned separately. In short, hither is how clone method industrial plant inward Java:
Since Object class' clone() method creates re-create yesteryear creating novel instance, as well as thence copying field-by-field, similar to assignment operator, it's fine for primitives as well as Immutable object, merely non suited if your shape contains roughly mutable information construction e.g. Collection classes like ArrayList or arrays. In that case, both master copy object as well as re-create of the object volition betoken to the same object inward the heap. You tin give the axe foreclose this yesteryear using the technique known equally deep cloning, on which each mutable champaign is cloned separately. In short, hither is how clone method industrial plant inward Java:
1) Any shape calls clone() method on an instance, which implements Cloneable and overrides protected clone() method from Object class, to exercise a copy.
Rectangle rec = new Rectangle(30, 60);
logger.info(rec);
try {
logger.info("Creating Copy of this object using Clone method");
Rectangle re-create = rec.clone();
logger.info("Copy " + copy);
} catch (CloneNotSupportedException ex) {
logger.debug("Cloning is non supported for this object");
}
2) Call to clone() method on Rectangle is delegated to super.clone(), which tin give the axe live a custom superclass or yesteryear default java.lang.Object
@Override
protected Rectangle clone() throws CloneNotSupportedException {
return (Rectangle) super.clone();
}
3) Eventually, telephone outcry upwards reaches to java.lang.Object's clone() method, which verify if the corresponding instance implements Cloneable interface, if non thence it throws CloneNotSupportedException, otherwise it creates a field-by-field re-create of the instance of that shape as well as returned to the caller.
So inward club for clone() method to operate properly, 2 things bespeak to happen, a class should implement Cloneable interface as well as should override clone() method of Object class.
By the way this was this was the simplest illustration of overriding clone method as well as how it works, things gets to a greater extent than complicated amongst existent object, which contains mutable fields, arrays, collections, Immutable object, and primitives, which nosotros volition run across inward second part of this Java Cloning tutorial series.
By the way this was this was the simplest illustration of overriding clone method as well as how it works, things gets to a greater extent than complicated amongst existent object, which contains mutable fields, arrays, collections, Immutable object, and primitives, which nosotros volition run across inward second part of this Java Cloning tutorial series.
Java clone() method Example
In this article, nosotros bring non seen complexity of overriding clone method inward Java, equally our Rectangle shape is really unproblematic as well as exclusively contains primitive fields, which agency shallow cloning provided yesteryear Object's clone() method is enough. But, this illustration is of import to sympathise the procedure of Object cloning inward Java, as well as how clone method works. Here is consummate code of this clone() method overriding example:
import org.apache.log4j.Logger;
/**
* Simple illustration of overriding clone() method inward Java to sympathise How Cloning of
* Object industrial plant inward Java.
*
* @author
*/
public class JavaCloneTest {
private static final Logger logger = Logger.getLogger(JavaCloneTest.class);
public static void main(String args[]) {
Rectangle rec = new Rectangle(30, 60);
logger.info(rec);
Rectangle re-create = null;
try {
logger.info("Creating Copy of this object using Clone method");
copy = rec.clone();
logger.info("Copy " + copy);
} catch (CloneNotSupportedException ex) {
logger.debug("Cloning is non supported for this object");
}
//testing properties of object returned yesteryear clone method inward Java
logger.info("copy != rec : " + (copy != rec));
logger.info("copy.getClass() == rec.getClass() : " + (copy.getClass() == rec.getClass()));
logger.info("copy.equals(rec) : " + copy.equals(rec));
//Updating fields inward master copy object
rec.setHeight(100);
rec.setWidth(45);
logger.info("Original object :" + rec);
logger.info("Clonned object :" + copy);
}
}
public class Rectangle implements Cloneable{
private int width;
private int height;
public Rectangle(int w, int h){
width = w;
height = h;
}
public void setHeight(int height) {
this.height = height;
}
public void setWidth(int width) {
this.width = width;
}
public int area(){
return widthheight;
}
@Override
public String toString(){
return String.format("Rectangle [width: %d, height: %d, area: %d]", width, height, area());
}
@Override
protected Rectangle clone() throws CloneNotSupportedException {
return (Rectangle) super.clone();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Rectangle other = (Rectangle) obj;
if (this.width != other.width) {
return false;
}
if (this.height != other.height) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 47 hash + this.width;
hash = 47 hash + this.height;
return hash;
}
}
Output:
2013-05-20 23:46:58,882 0 [main] INFO JavaCloneTest - Rectangle [width: 30, height: 60, area: 1800]
2013-05-20 23:46:58,882 0 [main] INFO JavaCloneTest - Creating Copy of this object using Clone method
2013-05-20 23:46:58,882 0 [main] INFO JavaCloneTest - Copy Rectangle [width: 30, height: 60, area: 1800]
2013-05-20 23:46:58,882 0 [main] INFO JavaCloneTest - re-create != rec : true
2013-05-20 23:46:58,882 0 [main] INFO JavaCloneTest - copy.getClass() == rec.getClass() : true
2013-05-20 23:46:58,882 0 [main] INFO JavaCloneTest - copy.equals(rec) : true
2013-05-20 23:46:58,882 0 [main] INFO JavaCloneTest - Original object :Rectangle [width: 45, height: 100, area: 4500]
2013-05-20 23:46:58,882 0 [main] INFO JavaCloneTest - Cloned object :Rectangle [width: 30, height: 60, area: 1800]
From the output, y'all tin give the axe clearly run across that cloned object has the same attribute equally the master copy object inward Java. Also changing the attribute of an master copy object is non affecting the solid soil of re-create object because they exclusively incorporate primitive fields. If they had contained whatever mutable object, it would bring affected both of them.
You tin give the axe too run across that it follow criterion properties of cloned object i.e.
You tin give the axe too run across that it follow criterion properties of cloned object i.e.
- clone != original,
- clone.getClass() == original.getClass(), and
- clone.equals(original).
Things to Remember - Clone method inward Java
1) The clone() method is used to exercise a re-create of an object inward Java. In club to purpose clone() method, shape must implement java.lang.Cloneable interface as well as override protected clone() method from java.lang.Object.
H5N1 telephone outcry upwards to clone() method volition final result inward CloneNotSupportedException if that shape doesn't implement Cloneable interface.
2) No constructor is called during cloning of Object inward Java.
3) Default implementation of clone() method inward Java provides "shallow copy" of object, because it creates re-create of Object yesteryear creating novel instance as well as thence copying content yesteryear assignment, which agency if your shape contains a mutable field, thence both master copy object as well as clone volition refer to same internal object. This tin give the axe live unsafe because whatever alter made on that mutable champaign volition reverberate inward both master copy as well as re-create object. In club to avoid this, override clone() method to render the deep re-create of an object.
4) By convention, clone of an instance should live obtained yesteryear calling super.clone() method, this volition assistance to save invariant of object created yesteryear clone() method i.e. clone != original as well as clone.getClass() == original.getClass(). Though these are non absolute requirement equally mentioned inward Javadoc.
5) H5N1 shallow re-create of an instance is fine, until it exclusively contains primitives as well as Immutable objects, otherwise, y'all bespeak to modify i or to a greater extent than mutable fields of object returned yesteryear super.clone(), earlier returning it to caller.
That's all on How clone method industrial plant inward Java. Now nosotros know, what is the clone as well as what is Cloneable interface, a pair of things almost clone method as well as what does default implementation of clone method exercise inward Java. This information is plenty to motility ahead as well as read second part of this Java cloning tutorial, on which nosotros volition learn, how to override clone() method inward Java, for classes composed amongst primitives, mutable as well as immutable objects inward Java.
Further Learning
Complete Java Masterclass
Java Fundamentals: The Java Language
Java In-Depth: Become a Complete Java Engineer!
Further Learning
Complete Java Masterclass
Java Fundamentals: The Java Language
Java In-Depth: Become a Complete Java Engineer!