Before we get to the formal topic, let's take a look at the next deep copy and the first copy concept:
Shallow copy:
Creates a new object that has an exact copy of the original object's attribute value, and if the attribute is a basic type, the copy is of the base type, and if the property is a memory address, the copy is the memory address, so if an object changes the address, it affects another object;
Deep copy:
Not only to copy all the unreferenced member variable values of the object, but also to create a new instance of the member variable of the reference type and initialize it to the formal parameter instance value;
After understanding the concepts, let's test whether the normal object assignment operation is a deep or shallow copy:
Test code:
public class Depthcopy {public
static void Main (string[] args) {
copy-a = new copy ("HzW");
Copy second = A;
Second.name = "Shanxi";
System.out.println (first.name);//Output Shanxi
}
}
class Copy
{public
String name;
public int age;
Public Copy (String Name,int age) {
this.name = name;
This.age = age;
}
It can be found that after second the Name property value to Shanxi, the Name property value of the primary becomes Shanxi, which shows that the normal object assignment is a shallow copy;
After we understand that the assignment between objects is a shallow copy, let's take a look at whether the clone is a deep or shallow copy, and the test code is to have the Copy object implement the Clone method in the Cloneable interface:
public class Depthcopy {public
static void Main (string[] args) {
copy-a = new copy ("HzW");
Copy second = null;
try {
second = (Copy) first.clone ();
} catch (Clonenotsupportedexception e) {
e.printstacktrace ();
}
Second.name = "Shanxi";
System.out.println (first.name);/output: HzW
System.out.println (a)//output: Com.hzw.day33.copy@7f39ebdb
System.out.println (second);/output: com.hzw.day33.copy@33abb81e
}
}
class Copy implements Cloneable
{public
String name;
public int age;
Public Copy (String Name,int age) {
this.name = name;
This.age = age;
}
@Override
protected Object Clone () throws Clonenotsupportedexception {return
super.clone ();
}
The
can see that the originally created object first and the clone created an object second is two instances, so the modification of the Name property in second does not affect the name attribute in first; but we can't simply think of cloning as a deep copy, For example, the following example:
public class Depthcopy {public static void main (string[] args) {Student Student = new Student (95);
Copy a = new copy ("HzW", 24,student);
Copy second = null;
try {second = (Copy) first.clone ();
catch (Clonenotsupportedexception e) {e.printstacktrace ();
} second.name = "Shanxi";
Second.student.score = 60; System.out.println (second);//false System.out.println (first.student = second.student);//true System.ou
T.println (First.student.score);//60}} class Copy implements cloneable {public String name;
public int age;
Public Student Student;
Public Copy (String name,int age,student Student) {this.name = name;
This.age = age;
This.student = student;
@Override protected Object Clone () throws Clonenotsupportedexception {return super.clone ();
} class Student {public int score;
Public Student (int score) {This.score = score; }
}
Did you see that? We created second by cloning, and it was clear that first and second were two instances, because the second output was false, but the student object in first and second was the same, After modifying the score value of student by second, the score in the initial student also changed, which means that the second inside the primary and student are the same, which means that the clone is a shallow copy, We want to achieve a deep copy of the clone, we must let the copy object inside the student object to implement the Cloneable interface inside the Clone method, and in the copy of the Cloning method to return student a clone, so that can guarantee student the only, The modified code is as follows:
public class Depthcopy {public static void main (string[] args) {Student Student = new Student (95);
Copy a = new copy ("HzW", 24,student);
Copy second = null;
try {second = (Copy) first.clone ();
catch (Clonenotsupportedexception e) {e.printstacktrace ();
} second.name = "Shanxi";
Second.student.score = 60; System.out.println (second);//false System.out.println (first.student = second.student);//false SYSTEM.O Ut.println (First.student.score);//95 System.out.println (Second.student.score);//60}} class Copy implements Clo
neable {public String name;
public int age;
Public Student Student;
Public Copy (String name,int age,student Student) {this.name = name;
This.age = age;
This.student = student;
@Override protected Object Clone () throws clonenotsupportedexception {copy copy = (copy) super.clone ();
copy.student = (student) student.clone ();return copy;
} class Student implements cloneable {public int score;
Public Student (int score) {This.score = score;
@Override protected Object Clone () throws Clonenotsupportedexception {return super.clone (); }
}
It can be seen that both the second and the first.student and the second.student are not the same at this time, so after we modify the student of second score it does not affect the student value of the score in the A, and achieves the purpose of deep copy.
However, if you think about the problem, it comes out, and if we have a reference type attribute in the student class of the example above, such as the college class, then we have to have the college class implement the Cloneable interface. Then in the student class inside the Clone method calls the College class's Clone method, in the copy class's Clone method calls the student class's Clone method, discovers that does not have, this process is very complex, You must have all of the relevant reference types in the class implement the Cloneable interface, feel good trouble is not, OK, then the cattle on the debut;
The best way to solve deep copy problem is to use serialization, so that all kinds of classes do not need to implement Cloneable interface, direct serialization of deserialization can be, let's see.
Import Java.io.File;
Import Java.io.FileInputStream;
Import Java.io.FileOutputStream;
Import Java.io.ObjectInputStream;
Import Java.io.ObjectOutputStream;
Import java.io.Serializable;
public class Depthcopy {public static void main (string[] args) {College school = new College ("Nongda");
Student Student = new Student (school);
Copy copy = new copy ("HzW", student); Copy another = null;//represents the deserialized class instance//serialization operation try {FileOutputStream fos = new FileOutputStream (New File ("
D:/copy.txt "));
ObjectOutputStream oos = new ObjectOutputStream (FOS);
Oos.writeobject (copy);
catch (Exception e) {e.printstacktrace ();
}//deserialization operation FileInputStream FIS;
try {fis = new FileInputStream (New File ("D:/copy.txt"));
ObjectInputStream ois = new ObjectInputStream (FIS);
another = (Copy) ois.readobject ();
catch (Exception e) {e.printstacktrace (); } System.out.println (copy = = another);//false System.out.println (copy.student = = another.student);//false System.out.println (Copy.stu
Dent.school = = Another.student.school);//false another.student.school.schoolName = "Wuda"; System.out.println (Copy.student.school.schoolName);//nongda}} class copy implements Serializable {public Strin
G name;
public int age;
Public Student Student;
Public Copy (String name,int age,student Student) {this.name = name;
This.age = age;
This.student = student;
} class Student implements Serializable {public int score;
Public College School;
Public Student (int Score,college school) {this.score = score;
This.school = School;
} class College implements Serializable {public String schoolname;
Public College (String schoolname) {this.schoolname = Schoolname; }
}
As you can see from the output, the object generated after deserialization is completely a copy of the original object, except that it has nothing to do with the original object, so when we modify the schoolname of the deserialized build object as "Wuda" Did not modify the original instance of the Schoolname value, or output "Nongda", so that the real deep copy effect, but to achieve serialization, all the relevant classes must implement the Serializable interface, This is always more convenient than implementing the Cloneable interface and implementing the Clone method.
The above is the Java deep copy and shallow copy of the detailed explanation, there is a need to refer to.