Java Enhancement-Object cloning (replication)

Source: Internet
Author: User
Tags serialization shallow copy

Read Catalogue


    • Why do you want to clone?
      How to implement cloning
      Shallow clones and deep clones
      Solving multi-layer cloning problems
      Summarize

Say you want to copy a simple variable. Very simple:

int apples = 5;  int pears = apples;  

More than just the int type, the other seven primitive data types (Boolean,char,byte,short,float,double.long) also apply to this type of case.

But if you're copying an object, it's a little bit more complicated.

Suppose that I was a beginner, I would write:

Class Student {      private int number;        public int GetNumber () {          return number;      }        public void Setnumber (int number) {          this.number = number;      }        }  public class Test {public            static void Main (String args[]) {          Student stu1 = new Student ();          Stu1.setnumber (12345);          Student stu2 = stu1;                    System.out.println ("Student 1:" + stu1.getnumber ());          System.out.println ("Student 2:" + Stu2.getnumber ());      }  }  

Results:

Student 1:12,345

Student 2:12,345

Here we customize a student class that has only one number field.

We created a new student instance and then assigned the value to the STU2 instance. (Student stu2 = STU1;)

Then look at the print results, as a novice, patted the chest belly, the object copy is so,

Is that really the case?

We try to change the number field of the STU2 instance, and then print the results to see:

Stu2.setnumber (54321);    System.out.println ("Student 1:" + stu1.getnumber ());  System.out.println ("Student 2:" + Stu2.getnumber ());  

Results:

Student 1:54,321

Student 2:54,321

This is strange, why change students 2 of the student number, students 1 of the school number has also changed?

The reason is in (STU2 = stu1) This sentence. The purpose of this statement is to assign a reference to the STU1 to STU2,

This way, STU1 and Stu2 point to the same object in the memory heap.

So, how can you replicate an object?

Do you remember the king of water object. It has 11 methods, with two protected methods, one of which is the Clone method.

In Java All classes are the default inherited from the Java language package of the object class, view its source code, you can copy your JDK directory Src.zip to other places and then unzip, inside is all the source code. There is a method clone () that has an access qualifier of protected in it:

/*creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent are that, for any object x, the Expression:1) x.clone ()! = x would be true2) X.clone (). GetClass () = = X.ge Tclass () would be true, but these was not absolute requirements.3) X.clone (). Equals (x) would be true, this is not an Absolut e requirement.*/protected native Object clone () throws Clonenotsupportedexception;

Look carefully, it is also a native method, we all know that the native method is a non-Java language implementation of the code for the Java program to call, because the Java program is running on the JVM virtual machine above, to access to the lower level of the operating system-related can no way, Can be implemented only by a language that is close to the operating system.

    1. The first declaration guarantees that the cloned object will have a separate memory address assignment.
    2. The second declaration indicates that the original and cloned objects should have the same class type, but it is not mandatory.
    3. The third statement indicates that the original and cloned objects should be equal to the Equals () method used, but it is not mandatory.

Because each class is a direct or indirect parent class that is object, they all contain the clone () method, but because the method is protected, it cannot be accessed outside the class.

To replicate an object, you need to overwrite the Clone method.

Back to the top why clone?

Let's start by thinking about a question, why do you need to clone objects? Is it okay to have a new object directly?

The answer is: The cloned object may contain some properties that have already been modified, and the properties of the new object are still initialized, so when a new object is needed to save the state of the current object, it depends on the clone method. So I'm assigning the temporary property of this object to my new object, right? can be, but one trouble not to say, and secondly, everyone through the above source has found that clone is a native method, is fast ah, at the bottom of the implementation.

To wake up, our Common Object A=new object (), object b;b=a; This form of code copies a reference, that is, an object's address in memory, and a and B objects still point to the same object.

The object that is assigned by the Clone method is independent of the original object.

Back to top how to implement cloning

Let's introduce two different cloning methods, shallow Clone (Shallowclone) and deep Clone (Deepclone).

In the Java language, data types are divided into value types (base data types) and reference types, and value types include simple data types such as int, double, Byte, Boolean, char, and reference types including complex types such as classes, interfaces, arrays, and so on. The main difference between shallow and deep clones is the support for replication of member variables of reference types, which are described in more detail below.

The general step is (shallow clone):

1. The replicated class needs to implement the Clonenable interface (if not implemented, the call to the Clone method throws a Clonenotsupportedexception exception), which is a markup interface (without any methods)

2. override the Clone () method to access the adornment subscript character topublic. method calls the Super.clone () method to get the desired copy object . (native as Local method)

The above method is modified below:

 class Student implements cloneable{private int number;      public int GetNumber () {return number;      } public void Setnumber (int number) {this.number = number;          } @Override Public Object clone () {Student stu = null;          try{stu = (Student) super.clone ();          }catch (clonenotsupportedexception e) {e.printstacktrace ();      } return Stu;          }} public class Test {public static void main (String args[]) {Student stu1 = new Student ();          Stu1.setnumber (12345);                    Student STU2 = (Student) stu1.clone ();          System.out.println ("Student 1:" + stu1.getnumber ());                    System.out.println ("Student 2:" + Stu2.getnumber ());                Stu2.setnumber (54321);          System.out.println ("Student 1:" + stu1.getnumber ());      System.out.println ("Student 2:" + Stu2.getnumber ()); }  }  

Results:

Student 1:12,345

Student 2:12,345

Student 1:12,345

Student 2:54,321

If you do not believe that these two objects are not the same object, then you can look at this sentence:

System.out.println (stu1 = = STU2); False  

The above replication is known as shallow cloning.

There is also a slightly more complex deep copy:

We add an address class to the student class.

 1 class Address {2 private String add;   3 4 public String Getadd () {5 return add;  6} 7 8 public void Setadd (String add) {9 This.add = add;  Ten}, and the class Student implements cloneable{the private int number;  Addr private Address;  Public Address getaddr () {return addr;  The public void setaddr (Address addr) {this.addr = addr;  The public int getnumber () {;  The public void Setnumber (int number) {this.number = number;  () {Student} (): () () () {stu = null;  try{stu = (Student) super.clone ();  }catch (clonenotsupportedexception e) {e.printstacktrace ();  * Stu return;     $48}, public class Test {47public static void Main (String args[]) {$ address addr = new address ();  Wuyi Addr.setadd ("Hangzhou city");  Student stu1 = new Student ();  Stu1.setnumber (123);  Stu1.setaddr (addr);  Student STU2 = (Student) stu1.clone ();  System.out.println ("Student 1:" + stu1.getnumber () + ", Address:" + stu1.getaddr (). Getadd ());  System.out.println ("Student 2:" + stu2.getnumber () + ", Address:" + stu2.getaddr (). Getadd ());   60} 61}

Results:

Student 1:123, Address: Hangzhou, China

Student 2:123, Address: Hangzhou, China

At first glance there's nothing wrong with that, is it?

We try to change the address of the addr instance in the Main method.

Addr.setadd ("West L. District");    System.out.println ("Student 1:" + stu1.getnumber () + ", Address:" + stu1.getaddr (). Getadd ());  System.out.println ("Student 2:" + stu2.getnumber () + ", Address:" + stu2.getaddr (). Getadd ());  

Results:

Student 1:123, Address: Hangzhou City  student 2:123, Address: Hangzhou  student 1:123, Address: West L. District  student 2:123, Address: West L. District  

It's strange how the address of two students has changed?

The reason is that shallow copy simply copies the reference to the addr variable, and does not really open up another space, copying the value and then returning the reference to the new object.

Therefore, in order to achieve a true copy of the object, instead of purely referencing replication. We need to copy the address class and modify the Clone method, the complete code is as follows:

 1 package ABC;   2 3 class Address implements cloneable {4 private String add;   5 6 Public String Getadd () {7 return add;  8} 9 public void Setadd (String add) {One this.add = add;  @Override the public Object clone () {Address addr = null;  try{addr = (Address) super.clone ();  }catch (clonenotsupportedexception e) {e.printstacktrace ();  a return of addr;  (+}) The class Student implements cloneable{private int number;  Addr private Address;  Public Address getaddr () {return addr;  Setaddr (Address addr) {this.addr = addr;  PNS} The public int getnumber () {+ # return number;  A. Setnumber public void (int number) {this.number = number; 45} 46 47 @Override-Public Object clone () {Student stu = null;   try{Wuyi stu = (Student) super.clone ();  Shallow copy}catch (Clonenotsupportedexception e) {e.printstacktrace ();   Stu.addr = (Address) addr.clone ();  Deep copy of Stu return;         * * * * * * public class Test {max public static void Main (String args[]) {62 63  Address addr = new address ();  Addr.setadd ("Hangzhou city");  Student stu1 = new Student ();  Stu1.setnumber (123);  Stu1.setaddr (addr);  Student STU2 = (Student) stu1.clone ();  System.out.println ("Student 1:" + stu1.getnumber () + ", Address:" + stu1.getaddr (). Getadd ());  System.out.println ("Student 2:" + stu2.getnumber () + ", Address:" + stu2.getaddr (). Getadd ());  Addr.setadd ("West L. District"); System.out.println ("Student 1:" + stu1.getnumber() + ", Address:" + stu1.getaddr (). Getadd ());  System.out.println ("Student 2:" + stu2.getnumber () + ", Address:" + stu2.getaddr (). Getadd ());   78} 79}

Results:

Student 1:123, Address: Hangzhou City  student 2:123, Address: Hangzhou  student 1:123, Address: West L. District  student 2:123, address: Hangzhou City  

The result is in line with our ideas.

Finally, let's take a look at one of the classes in the API that implements the Clone method:

Java.util.Date:

/**  * Return A copy of this object.  *  /Public Object clone () {      Date d = null;      try {          d = (Date) super.clone ();          if (CDate! = null) {              d.cdate = (basecalendar.date) cdate.clone ();}      } catch (Clonenotsupportedexception E ) {}//Won ' t happen      return D;  }  

This class actually belongs to the deep copy as well.

Reference Document: How Java copies objects

Back to top shallow clones and deep clones 1, shallow clones

In a shallow clone, if the member variable of the prototype object is a value type, a copy is copied to the cloned object, and if the member variable of the prototype object is a reference type, the address of the reference object is copied to the cloned object, meaning that the member variables of the prototype object and the cloned object point to the same memory address.

In simple terms, in a shallow clone, when an object is copied, only the member variables of itself and the value types contained therein are copied, and the member objects of the reference type are not copied.

In the Java language, shallow cloning can be achieved by overriding the Clone () method of the object class .

2, deep cloning

In a deep clone, regardless of whether the member variable of the prototype object is a value type or a reference type, a copy is copied to the Clone object, and a deep clone copies all the referenced objects of the prototype object to the cloned object.

In simple terms, in a deep clone, all the member variables contained in the object will be copied in addition to the object itself being copied.

In the Java language, if deep cloning is required, it can be implemented by overriding the Clone () method of the object class, or by serialization (serialization) .

( using the Clone method can be cumbersome if the reference type contains many reference types, or if the class of the inner reference type contains reference types.) In this case, we can implement the deep cloning of the object in a serialized way. )

Serialization is the process of writing an object to a stream, and the object written to the stream is a copy of the original object, and the original object still exists in memory. A copy implemented by serialization can not only copy the object itself, but also copy its referenced member objects, so it can be deeply cloned by serializing the object into a stream and then reading it out of the stream. It is important to note that objects that are capable of serializing have their classes implemented with the Serializable interface, otherwise they cannot implement serialization operations.

Extended
The Java language provides the Cloneable interface and the serializable interface code is very simple, they are empty interfaces, which is also known as the Identity interface, the identity of the interface does not have any method of definition, its role is to tell the JRE of the implementation class of these interfaces have a function, such as whether cloning is supported, serialization is supported, and so on.
Go back to the top to solve the problem of multilayer cloning

Using the Clone method can be cumbersome if the reference type contains many reference types, or if the class of the inner reference type contains reference types. In this case, we can implement the deep cloning of the object in a serialized way.

 1 public class Outer implements serializable{2 private static final long serialversionuid = 369285298572941L; It is best to explicitly declare ID 3 public Inner Inner; 4//discription:[Deep Copy method, requires the object and object all object properties are implemented serialization] 5 public Outer Myclone () {6 Outer Outer = null; 7 try {
   
       
    //serializes the object into a stream because it is written in a stream as a copy of the object, and the original object still exists inside the JVM. So using this feature allows you to implement a deep copy of the object  8 bytearrayoutputstream BAOs = new Bytearrayoutputstream (); 9 ObjectOutputStream oos = new ObjectOutputStream (BAOs), Oos.writeobject (this), 11//stream serialized to Object 1 2 Bytearrayinputstream Bais = new Bytearrayinputstream (Baos.tobytearray ()); ObjectInputStream ois = New ObjectInputStream (bais); outer = (outer) ois.readobject (); catch (IOException e) {E  . Printstacktrace (); n} catch (ClassNotFoundException e) {e.printstacktrace ();}20 return Outer;21}22} 
   

Inner must also implement serializable, otherwise it cannot be serialized:

1 public class Inner implements serializable{2   private static final long serialversionuid = 872390113109L;//preferably explicitly declare I D 3 public   String name = ""; 4  5 Public   Inner (string name) {6       this.name = name, 7   } 8  9   @Override10 public   String ToString () {One       return "inner name value is:" + name;12   }13}

This also enables two objects to exist completely independently in the memory space, and does not affect each other's values.

Back to top of the summary

There are two ways of implementing object cloning:

?? 1). Implement the Cloneable interface and override the Clone () method in the object class;

?? 2). Implement the Serializable interface, through the serialization and deserialization of objects to achieve cloning, you can achieve true deep cloning.

Note: clones based on serialization and deserialization are not just deep clones, but more importantly, by generic qualification, you can check that the object to be cloned supports serialization, which is done by the compiler, not by throwing an exception at run time. This scenario is significantly better than cloning an object using the Clone method of the object class. It is always better to let the problem be exposed at compile time than to leave the problem at runtime.

Article Links:

Java Advanced Series Object cloning

Java Basic notes – Deep copy of object and shallow copy implement Cloneable interface implementation shallow copy serialization for deep replication

An explanation of object cloning in Java

Java Object Cloning Guide

Cloning of objects-prototype mode (III)

Java Improvement Chapter (v)-----using serialization to implement a copy of an object

From:http://www.cnblogs.com/qian123/p/5710533.html

Java Enhancement-Object cloning (replication)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.