preface
Make writing a habit together! This is the fifth day of my participation in the “Gold Digging Day New Plan ยท April More text Challenge”. Click here for more details.
What would you say if you were asked, “What do you understand about deep copy and light copy?” There may be many friends do not understand the meaning and difference between deep copy and shallow copy, so today I would like to share with you my understanding of both ๐.
copy
Copying, as the name suggests, is to get the same object without having to create and assign it manually. Object Copy in Java refers to copying all properties of one Object to another Object of the same class type. Let’s take a small example ๐
There are two objects: object A and object B. Both objects belong to class XX, and both object A and object B have attributes A and B. The operation procedure for copying object A to object B is as follows: B.a = A.a; B.b = A.b;
Copying is often used when developing applications, mainly to reuse some (or all) of the data of existing objects in a new context. There are two main types of object Copy in Java: Shallow Copy and Deep Copy.
๐๐ Shallow copy ๐๐
First let’s take a look at what shallow copy means ๐
๐ฅ shallow copy ๐ฅ : passes values to the basic data type and makes reference-passing copies to the reference data type.
This may not be easy to understand, but let’s paraphrase it a little bit. For a member variable whose data type is the basic data type, the shallow copy directly transfers the value, that is, copies the attribute value to the new object. Because there are two different copies of data, modifying the value of the member variable in one object does not affect the data copied from the other object. For a data type is a member of the reference data type variables, such as the member variable is an array or object of a class, etc., the shallow copy will be for reference, that is just the reference value of the member variable (that is, the memory address) a copy to the new object, also said the two different objects of the member variables point to the same address, Changing the member variable in one object affects the data copied from the other. As shown in the following figure ๐
The clone() method can be overridden by implementing the Cloneable interface for the classes to be copied. Let’s look at the sample code:
/** * simulates the reference object *@description: Subject
* @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:43 * * /
public class Subject {
private String name;
public Subject(String name) {
this.name = name;
}
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(a) {
return "Subject{" +
"name='" + name + '\' ' +
'} '; }}Copy the code
/** ** class *@description: Person
* @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:43 * * /
public class Person implements Cloneable {
/** * references the data type */
private Subject subject;
/** * Base data type */
private String name;
/** * Base data type */
private int age;
public Subject getSubject(a) {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge(a) {
return age;
}
public void setAge(int age) {
this.age = age;
}
/** * Rewrite the clone() method *@return* /
@Override
public Object clone(a) {
/ / shallow copy
try {
// Call the clone() method of the parent directly
return super.clone();
} catch (CloneNotSupportedException e) {
return null; }}@Override
public String toString(a) {
return "[Person: " + this.hashCode() + ",subject:" + subject + ",name:" + name + ",age:" + age + "]"; }}Copy the code
/ * * *@description: Test
* @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:49 * * /
public class Test {
public static void main(String[] args) {
Subject subject = new Subject("Zhang");
Person personA = new Person();
personA.setSubject(subject);
personA.setName("Bill");
personA.setAge(20);
Person personB = (Person) personA.clone();
personB.setName("Fifty");
personB.setAge(18);
Subject subjectB = personB.getSubject();
subjectB.setName("Daisy");
System.out.println("PersonA:" + personA.toString());
System.out.println("PersonB:"+ personB.toString()); }}Copy the code
PersonB is copied from personA. Clone (), but personA and PersonB are two different objects. Changes to the underlying data types of personA and personB do not affect each other, and when the value of the reference subject is changed, the subject of the other object also changes.
๐๐ deep copy ๐๐
If we only want to modify the personA subject object, but the personB subject object is also modified, isn’t that a data security problem? So in some cases we need to use deep copy. Let’s first look at what deep copy means ๐
๐ฅ deep copy ๐ฅ : Passes values to the base data type, creates a new object for the reference data type, and copies its contents.
Deep copy has the following characteristics:
- For member objects of primitive data types, attribute values are assigned directly to the new object. A basic type of copy in which one object changes the value without affecting the other (as in a shallow copy).
- For reference types, such as arrays or class objects, deep copy creates a new object space and copies its contents, so they point to different memory Spaces. Changing one has no effect on the other (unlike shallow copy).
- For multiple layers of objects, Cloneable override clone() is required for each object, thus realizing serial layer copies of objects.
- Deep copy is slower and more expensive than shallow copy.
Now let’s modify the shallow copy code posted above to simulate the implementation of deep copy ๐
/** * simulates the reference object *@description: Subject
* @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:43 * * /
public class Subject implements Cloneable{
private String name;
public Subject(String name) {
this.name = name;
}
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone(a) throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString(a) {
return "Subject{" +
"name='" + name + '\' ' +
'} '; }}Copy the code
/** ** class *@description: Person
* @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:43 * * /
public class Person implements Cloneable {
/** * references the data type */
private Subject subject;
/** * Base data type */
private String name;
/** * Base data type */
private int age;
public Subject getSubject(a) {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
public String getName(a) {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge(a) {
return age;
}
public void setAge(int age) {
this.age = age;
}
/** * Overwrite the clone() method * if the Subject class also has reference objects, then we need to implement deep copy like the Person class *@return* /
@Override
public Object clone(a) {
/ / copy
try {
Person person = (Person) super.clone();
person.subject = (Subject) subject.clone();
return person;
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
return null; }}@Override
public String toString(a) {
return "[Person: " + this.hashCode() + ",subject:" + subject + ",name:" + name + ",age:" + age + "]"; }}Copy the code
/ * * *@description: Test
* @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:49 * * /
public class Test {
public static void main(String[] args) {
Subject subject = new Subject("Zhang");
Person personA = new Person();
personA.setSubject(subject);
personA.setName("Bill");
personA.setAge(20);
Person personB = (Person) personA.clone();
personB.setName("Fifty");
personB.setAge(18);
Subject subjectB = personB.getSubject();
subjectB.setName("Daisy");
System.out.println("PersonA:" + personA.toString());
System.out.println("PersonB:"+ personB.toString()); }}Copy the code
We can see from the result that after deep-copy objects, the modification of one object’s underlying data type variable or reference type member variable will not affect the other object.
We may not often use copy when developing applications, but distinguishing deep copy from shallow copy will give us a deeper understanding of the Java memory structure and how it works ๐ช.
summary
My experience is limited, some places may not be particularly in place, if you think of any questions when reading, welcome to leave a message in the comments section, we will discuss one by one ๐
Please take a thumbs up and a follow (โฟโกโฟโก) for this article ~ a crab (โ’โก’โ)
If there are mistakes in the article, welcome to comment correction; If you have a better, more unique understanding, you are welcome to leave your valuable ideas in the comments area.
Love what you love, do what you do, listen to your heart and ask nothing