Java中的深克隆和浅克隆

浅克隆: 创建一个新对象,新对象的属性和原来对象完全相同(新对象的地址 != 原来对象的地址),对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。**(String 类型除外)**。

深克隆: 创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

浅克隆示例:

1
2
3
4
class student  {
private String name;
private Integer age;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class teacher implements Cloneable {
private int[] drive;
private String name;
private Integer age;
private String sex;
private student stu;

@Override
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
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
public static void main(String[] args) {
teacher tea = new teacher();
int[] i = new int[1];
i[0]=88;
tea.setDrive(i);
tea.setName("老师");
student student = new student();
student.setAge(33);
student.setName("学生");
tea.setAge(56);
tea.setSex("男");
tea.setStu(student);


teacher clone = (teacher) tea.clone();
i[0] = 99;
clone.setDrive(i);
clone.setAge(78);
clone.setName("克隆老师");
clone.getStu().setAge(99);
clone.getStu().setName("小学生");

System.out.println(tea);
System.out.println(clone);
}
  • 结果

注意 此处只有基本数据类型被克隆 引用类型的地址并没有发生变化 Sting除外 因为String是final

1
2
teacher(drive=[99], name=老师, age=56, sex=男, stu=student(name=小学生, age=99))
teacher(drive=[99], name=克隆老师, age=78, sex=男, stu=student(name=小学生,age=99))

附图:

浅克隆UNL

深克隆示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class student implements Cloneable {
private String name;
private Integer age;
@Override
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
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
class teacher implements Cloneable {
private int[] drive;
private String name;
private Integer age;
private String sex;

private student stu;


// 注意此处
@Override
public Object clone() {
Object clone = null;
try {
clone = super.clone();
student clone1 = (student) this.getStu().clone();
this.setStu(clone1);
int[] clone2 = this.getDrive().clone();
this.setDrive(clone2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
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
public static void main(String[] args) {
teacher tea = new teacher();
int[] i = new int[1];
i[0] = 88;
tea.setDrive(i);
tea.setName("老师");
student student = new student();
student.setAge(33);
student.setName("学生");
tea.setAge(56);
tea.setSex("男");
tea.setStu(student);


teacher clone = (teacher) tea.clone();
i[0] = 99;
clone.setDrive(i);
clone.setAge(78);
clone.setName("克隆老师");
clone.getStu().setAge(99);
clone.getStu().setName("小学生");

System.out.println(tea);
System.out.println(clone);
}
  • 结果

注意结果发生明显的变化, 因为没个对象都被克隆 所有的引用都指向了不同的地址

1
2
teacher(drive=[88], name=老师, age=56, sex=男, stu=student(name=学生, age=33))
teacher(drive=[99], name=克隆老师, age=78, sex=男, stu=student(name=小学生, age=99))

附图:

深克隆UML