java clone 中的浅复制和深复制 (一)

2014-11-24 11:10:40 · 作者: · 浏览: 0

什么是浅复制?
首先,浅复制会创建一个新对象,这个新的对象各个字段的值会从原始对象复制过来,如果某个字段是引用其他的对象,那么仅仅复制此对象在内存中的引用地址。

如图1 所示,对象 MainObject1 有一个 int 类型的字段 Field1 和一个字段引用 ContainObject1对象,被克隆的新对象是 MainObject2, MainObject2 有一个 int 类型字段 Field2, Field2 的值是从对象MainObject1的字段 Field1 复制过来,而MainObject2的一个字段和MainObject1 中的某个字段仍然指向同一个对象ContainObject1,也就是说只要ContainObject1 发生任何变化,MainObject1 和MainObject2所引用的ContainObject1 都会用变化。

什么是深复制?
深复制也会创建一个新的对象,除了复制这个新对象里的原始类型字段的值,还要对此对象的引用字段再做克隆,而不是仅仅复制此引用字段再内存中的引用地址。

图2

如图2 所示,MainObject1 是原始对象,MainObject2 是被克隆出的对象,从图2和图1的差别可以看出,克隆对象MainObject2 字段ContainObject2和 MainObject1 里的字段 ContainObject1 指向的是不同的对象,也就是说,MainObject1 里的 ContainObject1 发生任何变化,都不会影响到 MainObject2 里的 ContainObject2。

用 java 实现浅复制示例:

[java]
class Subject {
private String name;

public String getName() {
return name;
}

public void setName(String s) {
name = s;
}

public Subject(String s) {
name = s;
}
}

class Student implements Cloneable {
//Contained object
private Subject subj;

private String name;

public Subject getSubj() {
return subj;
}

public String getName() {
return name;
}

public void setName(String s) {
name = s;
}

public Student(String s, String sub) {
name = s;
subj = new Subject(sub);
}

public Object clone() {
//shallow copy
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}

public class CopyTest {
public static void main(String[] args) {
//Original Object
Student stud = new Student("John", "Algebra");
System.out.println("Original Object: " + stud.getName() + " - "
+ stud.getSubj().getName());
//Clone Object
Student clonedStud = (Student) stud.clone();
System.out.println("Cloned Object: " + clonedStud.getName() + " - "
+ clonedStud.getSubj().getName());
stud.setName("Dan");
stud.getSubj().setName("Physics");
System.out.println("Original Object after it is updated: "
+ stud.getName() + " - " + stud.getSubj().getName());
System.out.println("Cloned Object after updating original object: "
+ clonedStud.getName() + " - " + clonedStud.getSubj().getName());

}
}

class Subject {
private String name;

public String getName() {
return name;
}

public void setName(String s) {
name = s;
}

public Subject(String s) {
name = s;
}
}

class Student implements Cloneable {
//Contained object
private Subject subj;

private String name;

public Subject getSubj() {
return subj;
}

public String getName() {
return name;
}

public void setName(String s) {
name = s;
}

public Student(String s, String sub) {
name = s;
subj = new Subject(sub);
}

public Object clone() {
//shallow copy
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}

public class CopyTest {
public static void main(String[] args) {
//Original Object
Student stud = new Student("John", "Algebra");
System.out.println("Original Object: " + stud.getNam