We know that in Java this interface cloneable, the class that implements the interface will have the ability to be copied, while the copy is in memory, in terms of performance than we directly through the new generation of objects, especially in the generation of large objects, so that the performance improvement is very obvious. However, we know that the copy is divided into deep copy and shallow copy, but shallow copy has the problem of incomplete copying of object attributes. For a deep copy, a shallow copy, please refer to here: gradual analysis of shallow and deep copy of Java
First, shallow copy problem
Let's look at the following code:
public class person implements cloneable{/** name **/private String name; /** email **/private email email; Public String GetName () {return name; } public void SetName (String name) {this.name = name; } public Email Getemail () {return email; } public void Setemail (email email) {This.email = email; The public person (String Name,email Email) {this.name = name; This.email = email; The public person (String name) {this.name = name; } Protected Person Clone () {person person = null; try {person = (person) super.clone (); } catch (Clonenotsupportedexception e) {e.printstacktrace (); } return person; }}public class Client {public static void main (string[] args) {//write email email = new email ("Please attend a meeting", " Please join the meeting today from 12:30 to two ... "); Person Person1 = new Person ("Zhang San", email); PErson Person2 = Person1.clone (); Person2.setname ("John Doe"); Person Person3 = Person1.clone (); Person3.setname ("Harry"); The message content of System.out.println (Person1.getname () + "is:" + person1.getemail (). getcontent ()); The message content of System.out.println (Person2.getname () + "is:" + person2.getemail (). getcontent ()); The message content of System.out.println (Person3.getname () + "is:" + person3.getemail (). getcontent ()); }}--------------------Output: Zhang San's message content is: Please join the meeting today from 12:30 to two ... John Doe's e-mail content is: Please join the meeting today from 12:30 to two ... Harry's e-mail content is: Please join the meeting today from 12:30 to two ...
In this application, first define a message, and then send the message to Zhang San, John Doe, Wang 53 people, because they are using the same message, and only the name is different, so use three of the object class copy John Doe, Harry object and then change the name. There's nothing wrong with the program all the time, but if we need a three to 30 minutes in advance, we'll change the contents of the email:
public class Client {public static void Main (string[] args) { //write email email = new email ("Please attend the meeting", "please contact today 12: 30 to two conference rooms to attend ... "); Person Person1 = new Person ("Zhang San", email); Person Person2 = person1.clone (); Person2.setname ("John Doe"); Person Person3 = person1.clone (); Person3.setname ("Harry"); Person1.getemail (). SetContent ("Please join the meeting today from 12:00 to two ..."); The message content of System.out.println (Person1.getname () + "is:" + person1.getemail (). getcontent ()); The message content of System.out.println (Person2.getname () + "is:" + person2.getemail (). getcontent ()); The message content of System.out.println (Person3.getname () + "is:" + person3.getemail (). getcontent ());} }
Here is also the use of three of the object to implement the John Doe, Harry Copy, and finally the contents of the Zhang San changed to: Please with today 12:00 to two conference room to attend the meeting .... But the result is:
Zhang San's e-mail content is: Please join the meeting today from 12:00 to two ... John Doe's e-mail content is: Please join the meeting today from 12:00 to two ... Harry's e-mail content is: Please join the meeting today from 12:00 to two ...
Here we wonder why the email content of John Doe and Harry also sent changes? Get them 30 minutes ahead of time to get a problem!
In fact, the key to the problem is the Clone () method, we know that the Clone () method is to use the Clone () method of the object class, but there is a flaw in the method, it does not copy all the properties of the object, but a selective copy, the basic rules are as follows:
1. Basic type
If the variable is of a basic type, copy its value, such as int, float, and so on.
2. Objects
If the variable is an instance object, copy its address reference, which means that the new object is public with the original object.
3, String strings
If the variable is a string literal, its address reference is copied. However, when modified, it regenerates a new string from the string pool, and the original purple Capital object remains unchanged.
Based on the above rules, we can easily find the problem, they three common object, Zhang San modified the content of the message, John Doe and Harry will also be modified, so the above situation occurs. We can still solve this situation by simply creating a new object within the Clone () method, and then Zhang San referencing the object:
Protected Person Clone () {person person = null; try {person = (person) super.clone (); Person.setemail (New Email (Person.getemail (). GetObject (), Person.getemail (). GetContent ())); } catch (Clonenotsupportedexception e) { e.printstacktrace (); } return person; }
So: Shallow copy is just a simple copy mechanism provided by Java, which is not easy to use directly.
There is still a problem with the solution above, if a large number of objects in our system are generated by copy, if we write a clone () method for each of our classes, and we will also need to make a deep copy and create a large number of objects, this project is very large, here we can use serialization to achieve the object copy.
Second, using serialization to achieve a copy of the object
How can I use serialization to accomplish a copy of an object? A copy of the byte stream in memory is relatively easy to implement. Write the parent object into a byte stream and read it out of the byte stream so that a new object can be created, and there is no reference sharing between the new object and the parent object, actually implementing the deep copy of the object.
public class Cloneutils { @SuppressWarnings ("unchecked") public static <t extends serializable> T Clone (t obj) { T cloneobj = null; try { //write byte stream bytearrayoutputstream out = new Bytearrayoutputstream (); ObjectOutputStream obs = new ObjectOutputStream (out); Obs.writeobject (obj); Obs.close (); Allocate memory, write to original object, generate new Object Bytearrayinputstream iOS = new Bytearrayinputstream (Out.tobytearray ()); ObjectInputStream ois = new ObjectInputStream (iOS); Returns the generated new object cloneobj = (T) ois.readobject (); Ois.close (); } catch (Exception e) { e.printstacktrace (); } return cloneobj;} }
Objects that use the tool class must implement the Serializable interface, otherwise there is no way to implement cloning.
public class person implements serializable{ private static final long serialversionuid = 2631590509760908280L; . ................. Remove Clone () method}public class Email implements serializable{ private static final long Serialversionuid = 1267293988171991494L; ....................}
So objects that use the tool class can implement the clone of the object as long as the serializable interface is implemented, without inheriting the Cloneable interface to implement the Clone () method.
public class Client {public static void Main (string[] args) { //write email email = new email ("Please attend the meeting", "please contact today 12: 30 to two conference rooms to attend ... "); Person Person1 = new Person ("Zhang San", email); Person Person2 = Cloneutils.clone (person1); Person2.setname ("John Doe"); Person Person3 = Cloneutils.clone (person1); Person3.setname ("Harry"); Person1.getemail (). SetContent ("Please join the meeting today from 12:00 to two ..."); The message content of System.out.println (Person1.getname () + "is:" + person1.getemail (). getcontent ()); The message content of System.out.println (Person2.getname () + "is:" + person2.getemail (). getcontent ()); The message content of System.out.println (Person3.getname () + "is:" + person3.getemail (). getcontent ());} } -------------------Output: Zhang San's e-mail content is: Please join the meeting today from 12:00 to two ... John Doe's e-mail content is: Please join the meeting today from 12:30 to two ... Harry's e-mail content is: Please join the meeting today from 12:30 to two ...
Consolidate the foundation, raise the technology, do not fear the difficulty, climb the peak!!!!!!
151 recommendations for writing high-quality code to improve Java programs----Qin Xiaobo
Java Improvement Chapter (VI)-----Using serialization to implement a copy of an object