- 浅复制
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。
看下面的例子
School类
public class School implements Cloneable{
private String name;
public School(String name){
this.name = name;
}
@Override
public String toString() {
return name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Student类
public class Student implements Cloneable{
private int age;
private School school;
public Student(){
System.out.println("init...");
}
@Override
protected Object clone() throws CloneNotSupportedException {
Student cloneStudent = (Student)super.clone();
return cloneStudent;
}
@Override
public String toString() {
return "age:"+age+" school:"+school;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
}
测试代码
Student s1 = new Student();
s1.setAge(20);
s1.setSchool(new School("java school"));
System.out.println("before clone s1 value is "+s1);
Student s2 = (Student)s1.clone();
s2.setAge(18);
s2.getSchool().setName("c++ school");
System.out.println("after clone s1 value is "+s1);
System.out.println("after clone s2 value is "+s2);
运行结果
init...
before clone s1 value is age:20 school:java school
after clone s1 value is age:20 school:c++ school
after clone s2 value is age:18 school:c++ school
由s1对象克隆来的s2对象,两个对象的成员变量school有相同的引用。
- 深复制
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。深复制把要复制的对象所引用的对象都复制了一遍。
将Student类的clone方法改为
@Override
protected Object clone() throws CloneNotSupportedException {
Student cloneStudent = (Student)super.clone();
cloneStudent.setSchool((School)this.school.clone());
return cloneStudent;
}
运行结果
init...
before clone s1 value is age:20 school:java school
after clone s1 value is age:20 school:java school
after clone s2 value is age:18 school:c++ school
- 使用串行化实现深复制
Student和School实现Serializable接口
Student添加方法
public Object deepClone() 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());
}
测试代码
Student s1 = new Student();
s1.setAge(20);
s1.setSchool(new School("java school"));
System.out.println("before clone s1 value is "+s1);
Student s2 = (Student)s1.deepClone();
s2.setAge(18);
s2.getSchool().setName("c++ school");
System.out.println("after clone s1 value is "+s1);
System.out.println("after clone s2 value is "+s2);
运行结果
init...
before clone s1 value is age:20 school:java school
after clone s1 value is age:20 school:java school
after clone s2 value is age:18 school:c++ school