原型模式,就是我有一个实例,但是我又不能直接用这个实例,那么就要基于这个实例拷贝一份,这就被称为原型模式。在java当中的Object方法里面提供了一个clone的方法可以使用,必须实现Cloneable接口,但是只能是浅拷贝,就是说如果说该实例下面有其它非基本类型的引用对象,并没有把这个引用对象重新拷贝一份。如果要进行深拷贝,就需要用到其它方法。直接上才艺
创建一个User对象
@Data
public class User implements Cloneable,Serializable {
private String name;
private Integer age;
private Dept dept;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
//浅拷贝
@Override
protected Object clone() throws CloneNotSupportedException {
return (User)super.clone();
}
//深拷贝
public Object deepClone() throws IOException, ClassNotFoundException {
/* 写入当前对象的二进制流 */
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/* 读出二进制流产生的新对象 */
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
创建一个引用对象Dept
@Data
public class Dept implements Cloneable, Serializable {
private String deptName;
private String deptNo;
public Dept(String deptName, String deptNo) {
this.deptName = deptName;
this.deptNo = deptNo;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return (Dept)super.clone();
}
}
测试
public class MainTest {
public static void main(String[] args) throws Exception{
User user = new User("张三",20);
Dept dept = new Dept("销售部", "007");
//使用浅拷贝
User user1=(User) user.clone();
System.out.println(user1.getAge());
System.out.println(user==user1);
System.out.println("..................");
user.setDept(dept);
//使用浅拷贝
User user2=(User)user.clone();
System.out.println(user2.getAge());
System.out.println(user==user2);
System.out.println(user.getDept()==user2.getDept());
System.out.println("..................");
//使用深拷贝
User user3=(User)user.deepClone();
System.out.println(user3.getAge());
System.out.println(user==user3);
System.out.println(user.getDept()==user3.getDept());
System.out.println("..................");
}
}
结果
20
false
..................
20
false
true
..................
20
false
false
..................
由结果可以看到,我们在使用浅拷贝的时候,下面引用的dept对象其实还是之前那一个,而采用深拷贝的时候,引用的dept对象才重新生成了一个对象。最后还有一个性能问题,我个人觉得不是很重要,记结论即可。如果构造函数比较简单,那么使用new效率更高,如果构造函数还要处理很多逻辑,大概率使用clone拷贝效率很更高点。具体逻辑多少,依据实际情况。