Shallow and deep copies of Java objects

Source: Internet
Author: User
Tags object serialization

we know that each object has the ability to copy its objects because each object is an object subclass, and object provides the Clone method, and a class implements the Cloneable interface to indicate that the class has the ability to be copied. If you overwrite the Clone method inside the copy is fully capable, the copy is in memory, so in terms of performance than directly through the new generation of objects much faster, especially in large object generation, which makes the performance of the increase is very significant, object provides the The Clone method is just a shallow copy, which means that it does not copy all of the properties of the object, but has a selective copy of the copy rule as follows:

Base type: Copies its value

Object: Copy the address reference, which means that the newly copied object shares the instance variable with the original object and is not restricted by access rights.

String : The copy is also an address, which is a reference, but when modified, it regenerates The new string from the string pool , and the original string object remains unchanged, where we can think String is a basic type.

Let's look at an example:

Define the person class, let it implement the Cloneable interface, add the corresponding attribute (name and father), and overwrite the Clone method in object:

Package Com.xin.suggestion;public class Person implements cloneable{private String name;private person father;public Person (String name) {this.name=name;} Public person (String Name,person father) {This.name=name;this.father=father;} Public String GetName () {return name;} public void SetName (String name) {this.name = name;} Public Person Getfather () {return father;} public void Setfather (person father) {this.father = Father;} Overwrite the Clone method in object @overrideprotected person clone () {person P=null;try {p= (person) super.clone ();p. Setfather (New Person (P.getfather (). GetName ()));} catch (Clonenotsupportedexception e) {e.printstacktrace ();} return p;} public static void Main (string[] args) {Man father=new person ("father"); Person Son1=new person ("big son", father);//The younger son and the older son have the same attributes, so copy the person from the older son Son2=son1.clone (); Son2.setname ("youngest son"); The father of System.out.println (Son1.getname () + "is:" +son1.getfather (). GetName ()); The father of System.out.println (Son2.getname () + "is:" +son2.getfather (). GetName ());}}

The results are as follows:

The father of the older son is: Father
The father of the youngest son is: Father
Let's look at the copy process:

Before the copy, the older son:

After the copy, the youngest son changed his name by SetName:

After the youngest son copied the big boy, for father, only copied its reference, so get the above results;

If the older son wants to recognize a godfather, we change the name of the father of the older son and change it to the Godfather:

public static void Main (string[] args) {Man father=new person ("father"); Person Son1=new person ("big son", father);//The younger son and the older son have the same attributes, so copy the person from the older son Son2=son1.clone (); Son2.setname (the "youngest son");//The older son recognized a father-in-the----and modified his dad's name Son1.getfather (). SetName ("Godfather"); The father of System.out.println (Son1.getname () + "is:" +son1.getfather (). GetName ()); The father of System.out.println (Son2.getname () + "is:" +son2.getfather (). GetName ());}

Printing results:

The father of the older son is: Godfather
The youngest son's father is: Godfather

This is good, the big son recognized the father-in-godfather, the youngest son also has to recognize the Godfather, this dad's two sons all recognized The Godfather, this is because we only modified the father's name, and two sons of its reference has not changed, as shown in:

So there will be the above results, the Clone method above only to achieve a shallow copy, and in fact we only need the big son to recognize the father-in-God, and the youngest child is his own son, so the real deep copy is the youngest son inside all the things are copied from the older sons, modify the Clone method:

Overwrite the Clone method in object @overrideprotected person clone () {person P=null;try {p= (person) super.clone ();//father does not just copy a quote, Instead, all copies a copy of P.setfather (New Person (P.getfather (). GetName ()));} catch (Clonenotsupportedexception e) {e.printstacktrace ();} return p;}

So we test the results above and get:

The father of the older son is: Godfather
The father of the youngest son is: Father
The deep copy method is illustrated below:

This deep copy means that both the older son and the youngest have a reference to their father, not just a copy of the reference to the father, here to achieve our deep copy, shallow copy is just Java provides a simple copy mechanism, it is not convenient for us to use directly.

When we are copying objects, we recommend using the method of object serialization to copy, in memory through the byte stream copy of the way to achieve, is to write the parent object into a byte stream, and then read it from the byte stream, so that a new object can be rebuilt, there is no reference sharing between the new object and the parent object , it is equivalent to a deep copy of a new object, it is recommended to use this method, the following is a copy of a tool class:

public class Cloneutils {@SuppressWarnings ("unchecked") public static <t extends serializable> T clone (T obj) {// Copy produced object T cloneobj=null;try {//Read object byte data bytearrayoutputstream baos=new bytearrayoutputstream (); ObjectOutputStream Oos =new ObjectOutputStream (BAOs); Oos.writeobject (obj); oos.close ();//Allocate memory space, write to original object, generate new object Bytearrayinputstream bais= New Bytearrayinputstream (Baos.tobytearray ()); ObjectInputStream ois=new ObjectInputStream (Bais);//Returns the object And do the type to replace cloneobj= (T) ois.readobject (); Ois.close ();} catch (IOException e) {e.printstacktrace ();} catch (ClassNotFoundException e) {e.printstacktrace ();} return cloneobj;}}

The test relies on a serialized approach for deep copying:

package Com.xin.suggestion;import Java.io.serializable;public class Person2 implements serializable{/** * */private static Final Long serialversionuid = 4389118360256841607l;private string name;private Person2 father;public Person2 (string name ) {this.name=name;} Public Person2 (String name,person2 father) {This.name=name;this.father=father;} Public String GetName () {return name;} public void SetName (String name) {this.name = name;} Public Person2 Getfather () {return father;} public void Setfather (Person2 father) {this.father = Father;} public static void Main (string[] args) {Person2 father=new Person2 ("father"); Person2 son1=new Person2 ("The older Son", father);//Use a serialized method for deep copy Person2 Son2=cloneutils.clone (son1); Son1.getfather (). SetName ("Godfather"); Son2.setname ("youngest son"); The father of System.out.println (Son1.getname () + "is:" +son1.getfather (). GetName ()); The father of System.out.println (Son2.getname () + "is:" +son2.getfather (). GetName ());}} 

Output Result:

The father of the older son is: Godfather
The father of the youngest son is: Father
To copy using this method, you need to be aware that:
1. The internal properties of an object are serializable, and if there are internal properties that are not serializable, a serialization exception is thrown
2. Note the special modifiers for methods and properties: For example, the serialization of final and static variables is introduced into the object copy, which requires special attention, while transient variables (transient variables, non-serialized variables) also affect the copy effect
For example, in the Father property above, add it transient keyword: private transient Person2 father, then the results will appear nullpointexception, so use caution.

In the case of serialized copy, there is also a simpler way, is the use of Apache under the Commons toolkit of the Serializationutils class, direct use of more concise and convenient, we can do their own research.

Shallow and deep copies of Java objects

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.