一.简介
⑴浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
⑵深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
二.测试与实现
1.实现步骤:
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。
2.测试代码:
职位类
package designPatterns.createPattern.copy;
import java.io.Serializable;
public class Profession implements Serializable {
private static final long serialVersionUID = 9051L;
private String position;//职位的名称
public Profession(String position) {
this.position = position;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
}
人的实体类
package designPatterns.createPattern.copy;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class People implements Cloneable, Serializable {
private static final long serialVersionUID = 9050L;
private String name;
private int age;
private Profession profession = new Profession();
public People(String name, int age, Profession profession) {
this.name = name;
this.age = age;
this.profession = profession;
}
//浅复制
public Object clone() {
People people = null;
try {
people = (People) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return people;
}
//利用串行化来做深复制
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());
}
// 用于展示类的字段信息
public void printPeopleInfo() {
System.out.println("name:" + name + "\tage:" + age + "\tprofession:" + profession.getPosition());
}
public Profession getProfession() {
return profession;
}
}
测试一:浅复制
public class Test {
public static void main(String[] args) throws ClassNotFoundException, IOException {
People a = new People("ins", 24, new Profession("programmer"));
People b = (People) a.clone();
//打印结果
a.printPeopleInfo();
b.printPeopleInfo();
//对职位修改
a.getProfession().setPosition("manager");
//打印结果
a.printPeopleInfo();
b.printPeopleInfo();
}
}
测试一结果:
name:ins age:24 profession:programmer
name:ins age:24 profession:programmer
name:ins age:24 profession:manager
name:ins age:24 profession:manager
测试二:深复制
public static void main(String[] args) throws ClassNotFoundException, IOException {
People a = new People("ins", 24, new Profession("programmer"));
People b = (People) a.deepClone();
//打印结果
a.printPeopleInfo();
b.printPeopleInfo();
//对职位修改
a.getProfession().setPosition("manager");
//打印结果
a.printPeopleInfo();
b.printPeopleInfo();
}
测试二结果:
name:ins age:24 profession:programmer
name:ins age:24 profession:programmer
name:ins age:24 profession:manager
name:ins age:24 profession:programmer
三.备注与总结
深复制,之所以采用串行化做的原因是为了避免重写比较复杂对象的深复制的clone()方法,也可以程序实现断点续传等等功能.
由上面的代码和结果可以更加直接的理解浅克隆和深克隆.