Java 深复制和浅复制
信息
日期 : 2016-7-5 7:12:30
基本概念
浅复制:
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深复制:
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
深复制(clone())
- 实现
Cloneable
接口,对象的引用也需要实现该方法。
- 重载
clone()
方法。
具体代码
Teacher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | public class Teacher implements Cloneable, Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
|
Student
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 | public class Student implements Cloneable, Serializable{
private String name;
private Teacher teacher;
public Student(String name, Teacher teacher) {
this.name = name;
this.teacher = teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Student student = null;
student = (Student) super.clone();
student.teacher = (Teacher) student.teacher.clone();
return student;
}
//深复制
public Object deepCopy () throws IOException, ClassNotFoundException {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
//从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
|
测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | public class StudentTest {
@Test
public void testDeepCopy() throws CloneNotSupportedException, IOException, ClassNotFoundException {
Teacher teacher = new Teacher("teacher");
Student student = new Student("student", teacher);
//进行深复制
Student studentCopy = (Student) student.clone();
Student studentCopy1 = (Student) student.deepCopy();
//
Assert.assertNotEquals(student, studentCopy);
Assert.assertNotEquals(student.getTeacher(), studentCopy.getTeacher());
Assert.assertNotEquals(student.getTeacher(), studentCopy1.getTeacher());
}
}
|
深复制---序列化实现
在Java中有一个 Serializable
接口,实现该接口的对象都有一个序列化标志,可以直接使用java的对象写入方法,把实现序列化接口的对象写入到输出流中,然后再把输入流转换为对象,由此可以实现对象的深层复制。通过一些java关键字的控制,可以屏蔽一些不想复制的字段。
具体代码
Teacher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | public class Teacher implements Cloneable, Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
|
Student
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 | public class Student implements Cloneable, Serializable{
private String name;
private Teacher teacher;
public Student(String name, Teacher teacher) {
this.name = name;
this.teacher = teacher;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Student student = null;
student = (Student) super.clone();
student.teacher = (Teacher) student.teacher.clone();
return student;
}
//深复制
public Object deepCopy () throws IOException, ClassNotFoundException {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
//从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
|
测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | public class StudentTest {
@Test
public void testDeepCopy() throws CloneNotSupportedException, IOException, ClassNotFoundException {
Teacher teacher = new Teacher("teacher");
Student student = new Student("student", teacher);
//进行深复制
Student studentCopy = (Student) student.clone();
Student studentCopy1 = (Student) student.deepCopy();
//
Assert.assertNotEquals(student, studentCopy);
Assert.assertNotEquals(student.getTeacher(), studentCopy.getTeacher());
Assert.assertNotEquals(student.getTeacher(), studentCopy1.getTeacher());
}
}
|