拷贝,字面理解就是为了获得一份相同的数据。顾名思义就是为了获得一个相同的对象,而不需要我们再人为的创建和赋值
在Java中如何理解深拷贝和浅拷贝呢?它们的区别又是什么?

1.1 浅拷贝

对基本数据类型进行值传递,对引用数据类型是引用地址值拷贝,此为浅拷贝。
浅拷贝

1.2 深拷贝

** 对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。**
深拷贝

1.3 代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package com.apps.test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/*
java中的拷贝需要实现java.lang.Cloneable接口,
然后重写clone()方法,这个无论深、浅拷贝都需要这样做
类要想可序列化就需要实现java.io.Serializable接口,
Cloneable、Serializable相当于标识,有这个标识才能使用Object的方法拷贝
*/

class Student implements Cloneable,Serializable { //学生类

public String name;
public int age;
public School s;

public Student() {
super();
}

public Student(String name, int age, School s) {
super();
this.name = name;
this.age = age;
this.s = s;
}

//使用Object()的clone()方法完成浅拷贝
public Student shallowClone() throws CloneNotSupportedException {
//调用父类的clone()方法,它是浅拷贝操作
return (Student) super.clone();
}

//使用序列化来完成深拷贝
public Student deepClone() throws Exception {
//序列化
FileOutputStream fos = new FileOutputStream("./sequence.hk");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(shallowClone());
//反序列化
FileInputStream fis = new FileInputStream("./sequence.hk");
ObjectInputStream ois = new ObjectInputStream(fis);
return (Student) ois.readObject();
}

@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", s=" + s + "]";
}

}

class School implements Serializable { //学校类
public String name;
public int number;

public School() {
super();
}

public School(String name, int number) {
super();
this.name = name;
this.number = number;
}

@Override
public String toString() {
return "School [name=" + name + ", number=" + number + "]";
}

}

public class Demo {

public static void main(String [] args) throws Exception{
//浅拷贝
School sch = new School("清华大学",200000);
Student stu = new Student("张三",20,sch);
//调用方法
Student stu2 = stu.shallowClone();
System.out.println(stu);
System.out.println(stu2);
//修改stu的引用属性
stu.s.number = 300000;
System.out.println(stu);
System.out.println(stu2);

/* 打印结果
Student [name=张三, age=20, s=School [name=清华大学, number=200000]]
Student [name=张三, age=20, s=School [name=清华大学, number=200000]]

Student [name=张三, age=20, s=School [name=清华大学, number=300000]]
Student [name=张三, age=20, s=School [name=清华大学, number=300000]]
*/

可以看到我们修改stu的引用属性,发现stu2也跟着发生了修改,这就是浅拷贝

System.out.println("----------------------");

//深拷贝
School sch2 = new School("哈佛大学",500000);
Student stu3 = new Student("王二",20,sch2);
//调用方法
Student stu4 = stu3.deepClone();
System.out.println(stu3);
System.out.println(stu4);
//修改stu的引用属性
stu3.s.number = 600000;
System.out.println(stu3);
System.out.println(stu4);

/* 打印结果
Student [name=王二, age=20, s=School [name=哈佛大学, number=500000]]
Student [name=王二, age=20, s=School [name=哈佛大学, number=500000]]

Student [name=王二, age=20, s=School [name=哈佛大学, number=600000]]
Student [name=王二, age=20, s=School [name=哈佛大学, number=500000]]
*/

可以看到我们修改stu3的引用属性,发现stu4并没有发生了修改,这就是深拷贝
}

}