How Clone Method Plant Inward Java?

The clone() is a tricky method from java.lang.Object class, which is used to practice a re-create of an Object inwards Java. The intention of the clone() method is simple, to render a cloning mechanism, only somehow it's implementation became tricky together with has been widely criticized from a long time. Anyway, nosotros volition non boot the bucket to classic fence of clone inwards Java, at to the lowest degree for now; instead, nosotros volition endeavour to larn how clone method plant inwards Java. To live fair, understating cloning machinery inwards Java is non slow together with fifty-fifty experienced Java programmer neglect to explicate how cloning of mutable object works, or a difference betwixt deep together with shallow re-create inwards Java.

In this three-part article, nosotros volition get-go run into working of clone method inwards Java, together with inwards 2nd purpose nosotros volition larn how to override clone method inwards Java, together with endure nosotros volition verbalise over deep re-create vs shallow copy mechanism.

The argue I chose to brand this a three-part article is to boot the bucket on the focus on 1 affair at a time. Since clone() itself is confusing enough, it's best to sympathise concept 1 past times one. In this post, nosotros volition larn what is clone method, what it does together with How clone method plant inwards Java.

By the way, clone() is 1 of the few key methods defined past times objects, others existence equals, hashcode(), toString() along amongst hold back together with notify methods.



What is the clone of an object inwards Java?

An object which is returned past times the clone() method is known every bit a clone of master copy instance. H5N1 clone object should follow basic characteristics e.g. a.clone() != a, which way master copy together with clone are 2 split upwards object inwards Java heap, a.clone().getClass() == a.getClass() together with clone.equals(a), which way clone is exact re-create of master copy object. This feature is followed past times a good behaved, correctly overridden clone() method inwards Java, only it's non enforced past times the cloning mechanism. Which means, an object returned past times clone() method may violate whatever of these rules.

By next the convention of returning an object past times calling super.clone(), when overriding clone() method, you lot tin ensure that it follows get-go 2 characteristics. In venture to follow the 3rd characteristic, you lot must override equals method to enforce logical comparison, instead of physical comparing exists inwards java.lang.Object.

For example, clone() method of Rectangle flat inwards this method render object, which has these characteristics, only if you lot run the same programme past times commenting equals(), you will run into that 3rd invariant i.e. clone.equals(a) volition render false. By the way at that topographic point are a couplet of skillful items on Effective Java regarding effective utilisation of clone method, I highly recommend to read those items later going through this article.



How Clone method plant inwards Java

protected together with native in Object class, thus implemented inwards native code. Since its convention to render clone() of an object past times calling super.clone() method, whatever cloning procedure eventually reaches to java.lang.Object clone() method. This method, get-go checks if the corresponding object implements Cloneable interface, which is a marking interface. If that instance doesn't implement Cloneable together with thus it throws CloneNotSupportedException inwards Java, a checked exception, which is ever required to live handled piece cloning an object. If an object passes this check, than java.lang.Object's clone() method creates a shallow re-create of the object together with returned it to the caller.


Since Object class' clone() method creates re-create past times creating novel instance, together with and thus copying field-by-field, similar to assignment operator, it's fine for primitives together with Immutable object, only non suited if your flat contains roughly mutable information construction e.g. Collection classes like ArrayList or arrays. In that case, both master copy object together with re-create of the object volition betoken to the same object inwards the heap. You tin foreclose this past times using the technique known every bit deep cloning, on which each mutable champaign is cloned separately. In short, hither is how clone method plant inwards Java:



1) Any flat calls clone() method on an instance, which implements Cloneable and overrides protected clone() method from Object class, to practice 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 live a custom superclass or past times default java.lang.Object

    @Override
    protected Rectangle clone() throws CloneNotSupportedException {
        return (Rectangle) super.clone();
    }



3) Eventually, telephone telephone reaches to java.lang.Object's clone() method, which verify if the corresponding instance implements Cloneable interface, if non together with thus it throws CloneNotSupportedException, otherwise it creates a field-by-field re-create of the instance of that flat together with returned to the caller.

So inwards venture for clone() method to locomote properly, 2 things take away to happen, a class should implement Cloneable interface together with should override clone() method of Object class.

By the way this was this was the simplest illustration of overriding clone method together with 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 into inwards second part of this Java Cloning tutorial series.

Here is how  a shallow re-create of an object looks like:

 which is used to practice a re-create of an Object inwards Java How clone method plant inwards Java?


Java clone() method Example

In this article, nosotros accept non seen complexity of overriding clone method inwards Java, every bit our Rectangle flat is real unproblematic together with exclusively contains primitive fields, which way shallow cloning provided past times Object's clone() method is enough. But, this illustration is of import to sympathise the procedure of Object cloning inwards Java, together with 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 inwards Java to sympathise How Cloning of
  * Object plant inwards 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 past times clone method inwards 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 inwards 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:
2019-05-20 23:46:58,882 0    [main] INFO  JavaCloneTest  - Rectangle [width: 30, height: 60, area: 1800]
2019-05-20 23:46:58,882 0    [main] INFO  JavaCloneTest  - Creating Copy of this object using Clone method
2019-05-20 23:46:58,882 0    [main] INFO  JavaCloneTest  - Copy Rectangle [width: 30, height: 60, area: 1800]

2019-05-20 23:46:58,882 0    [main] INFO  JavaCloneTest  - re-create != rec : true
2019-05-20 23:46:58,882 0    [main] INFO  JavaCloneTest  - copy.getClass() == rec.getClass() : true
2019-05-20 23:46:58,882 0    [main] INFO  JavaCloneTest  - copy.equals(rec) : true

2019-05-20 23:46:58,882 0    [main] INFO  JavaCloneTest  - Original object :Rectangle [width: 45, height: 100, area: 4500]

2019-05-20 23:46:58,882 0    [main] INFO  JavaCloneTest  - Cloned object  :Rectangle [width: 30, height: 60, area: 1800]

From the output, you lot tin clearly run into that cloned object has the same attribute every bit the master copy object inwards Java. Also changing the attribute of an master copy object is non affecting the Earth of re-create object because they exclusively comprise primitive fields. If they had contained whatever mutable object, it would accept affected both of them.

You tin too run into 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 inwards Java


1) The clone() method is used to practice a re-create of an object inwards Java. In venture to utilisation clone() method, flat must implement java.lang.Cloneable interface together with override protected clone() method from java.lang.Object.

H5N1 telephone telephone to clone() method volition outcome inwards CloneNotSupportedException if that flat doesn't implement Cloneable interface.


2) No constructor is called during cloning of Object inwards Java.


3) Default implementation of clone() method inwards Java provides "shallow copy" of object, because it creates re-create of Object past times creating novel instance together with and thus copying content past times assignment, which way if your flat contains a mutable field, together with thus both master copy object together with clone volition refer to same internal object. This tin live unsafe because whatever modify made on that mutable champaign volition reverberate inwards both master copy together with re-create object. In venture 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 past times calling super.clone() method, this volition help to save invariant of object created past times clone() method i.e. clone != original together with clone.getClass() == original.getClass(). Though these are non absolute requirement every bit mentioned inwards Javadoc.


5) H5N1 shallow re-create of an instance is fine, until it exclusively contains primitives together with Immutable objects, otherwise, you lot take away to modify 1 or to a greater extent than mutable fields of object returned past times super.clone(), earlier returning it to caller.


That's all on How clone method plant inwards Java. Now nosotros know, what is the clone together with what is Cloneable interface, a couplet of things almost clone method together with what does default implementation of clone method practice inwards Java. This information is plenty to movement ahead together with read second part of this Java cloning tutorial, on which nosotros volition learn, how to override clone() method inwards Java, for classes composed amongst primitives, mutable together with immutable objects inwards Java.


Further Learning
Complete Java Masterclass
Java Fundamentals: The Java Language
Java In-Depth: Become a Complete Java Engineer!

Belum ada Komentar untuk "How Clone Method Plant Inward Java?"

Posting Komentar

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel