java学习笔记之原型模式及深浅拷贝

image-20200517144621628

一、原型模式的基本介绍

在聊原型模式之前,我们来思考一个小问题,传统的方式我们是如何克隆对象呢?

那我们以多利羊(Sheep)为例,来说明上述这个问题,具体代码见下面:

多利羊(Sheep)

public class Sheep { private String sname; private Date birthday; public Sheep(String sname, Date birthday) { this.sname = sname; this.birthday = birthday; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } }

测试类(Client)

public class Client { public static void main(String[] args) { Sheep sheep=new Sheep("多利",new Date()); Sheep sheep2=new Sheep(sheep.getSname(),sheep.getBirthday()); System.out.println("sheep:"+sheep.getSname()+sheep.getBirthday()); System.out.println("sheep2:"+sheep2.getSname()+sheep2.getBirthday()); } }

那我们来分析一下:

1、在创建新对象时,总是需要获取原始对象的属性,如果我们在实际项目中创建的对象复杂的话,效率是很低的。

2、总是需要重新初始化对象,而不是动态地获取对象运行时的状态,不够灵活。

有什么方法可以改进吗?,原型模式闪亮登场

大家都知道在Java中有一个Object类,这个类提供了一个clone()方法,该方法可以将Java对象复制一份,前提是该类实现一个Cloneable接口,这就是原型模式的源头。

什么是原型模式:

用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。

看了这个定义可能有的小伙伴们比较蒙,那我们来撸一把代码来说明(多利羊克隆):

多利羊(Sheep)实现Cloneable

public class Sheep implements Cloneable { private String sname; private Date birthday; private Sheep mother; public Sheep getMother() { return mother; } public void setMother(Sheep mother) { this.mother = mother; } public Sheep(String sname, Date birthday) { this.sname = sname; this.birthday = birthday; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "Sheep{" + "sname='" + sname + '\'' + ", birthday=" + birthday + '}'; } @Override protected Object clone() throws CloneNotSupportedException { Sheep sheep=null; try { sheep=(Sheep) super.clone(); }catch (Exception e){ e.printStackTrace(); } return sheep; } }

克隆方法的测试(Client)

public class Client { public static void main(String[] args) throws CloneNotSupportedException { Sheep sheep=new Sheep("多利",new Date()); Sheep mother=new Sheep("多利的妈妈",new Date()); sheep.setMother(mother); Sheep sheep1=(Sheep) sheep.clone(); System.out.println("sheep:"+sheep); System.out.println("sheep1:"+sheep1); System.out.println("sheep:"+sheep.getMother().hashCode()); System.out.println("sheep1:"+sheep1.getMother().hashCode()); } }

运行结果:hashcode 的值一样

sheep:Sheep{sname='多利', birthday=Sun May 17 11:56:58 CST 2020}
sheep1:Sheep{sname='多利', birthday=Sun May 17 11:56:58 CST 2020}
sheephashcode:2061475679
sheep1hashcode:2061475679

二、原型模式实现浅克隆和深克隆

浅克隆的介绍:

对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。

对于数据类型是引用数据类型的成员变量(数组,对象),浅拷贝会进行引用传递,也就是将成员变量的引用值(内存地址)复制一份给新的对象,因为实际上两个对象的该成员变量都指向同一个实例(前面克隆羊就是浅拷贝,使用clone()方法实现)。

再次说明:其实就是克隆多利羊之后,克隆的对象没有被真正的复制一份,而是引用指向第一个对象的属性空间。

画图说明:

image-20200517121722748

具体代码如下见上面(多利羊克隆)

深克隆的介绍:

1、对对象进行深拷贝要对整个对象(包括对象的引用类型)进行拷贝。

image-20200517124535384

深克隆实现的方式:

1、重写clone()方法实现深克隆

2、通过对象序列化实现深克隆

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyszzd.html