4. 原型模式
使用原型去拷贝出多个对象
克隆羊案例:
/** * @author wuyimin * @create 2021-07-25 16:51 * @description 实现克隆接口,调用父类的克隆方法 */ public class Sheep implements Cloneable { String name; int age; public Sheep(String name, int age) { this.name = name; this.age = age; } public Sheep() { } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Sheep clone() throws CloneNotSupportedException { Sheep sheep=null; sheep=(Sheep) super.clone(); return sheep; } }
浅拷贝问题--修改原型引用传递的值会导致拷贝的对象的值也跟着改变
/** * @author wuyimin * @create 2021-07-25 16:51 * @description 实现克隆接口 */ public class Sheep implements Cloneable { String name; int age; //新增friend属性 Sheep friend; public Sheep getFriend() { return friend; } public void setFriend(Sheep friend) { this.friend = friend; } public Sheep(String name, int age) { this.name = name; this.age = age; } public Sheep() { } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Sheep clone() throws CloneNotSupportedException { Sheep sheep=null; sheep=(Sheep) super.clone(); return sheep; } }
/** * @author wuyimin * @create 2021-07-25 16:53 * @description 测试 */ public class MyTest { @Test public void test() throws CloneNotSupportedException { Sheep sheep = new Sheep("多利",3); sheep.setFriend(new Sheep("刘子",2)); Sheep clone = sheep.clone(); //对于浅拷贝会直接拿到引用传递的地址进行拷贝 System.out.println(clone.getFriend() == sheep.getFriend());//true System.out.println(clone); } }
深拷贝的两种实现方式-序列化、重写clone方法
A类依赖于B类
重写clone方法
/** * @author wuyimin * @create 2021-07-25 17:22 * @description 这里因为测试类不在一个包下面把方法改成public了 */ public class A implements Cloneable,Serializable{ private String aName; private B bObject; public A(String aName, B bObject) { this.aName = aName; this.bObject = bObject; } public String getaName() { return aName; } public void setaName(String aName) { this.aName = aName; } public B getbObject() { return bObject; } public void setbObject(B bObject) { this.bObject = bObject; } @Override public A clone() throws CloneNotSupportedException { A a=null; a=(A) super.clone(); a.bObject=bObject.clone(); return a; } } /** * @author wuyimin * @create 2021-07-25 17:23 * @description 这里因为测试类不在一个包下面把方法改成public了 * */ public class B implements Cloneable,Serializable{ String bName; public B(String bName) { this.bName = bName; } @Override public B clone() throws CloneNotSupportedException { B b=null; b=(B)super.clone(); return b; } }
测试
@Test public void test2() throws CloneNotSupportedException { A a=new A("111",new B("111")); A clone = a.clone(); System.out.println(a.getbObject()==clone.getbObject());//false }
序列化方式(推荐)
/** * @author wuyimin * @create 2021-07-25 17:22 * @description 序列化方法 */ public class A implements Serializable { private String aName; private B bObject; public A(String aName, B bObject) { this.aName = aName; this.bObject = bObject; } public String getaName() { return aName; } public void setaName(String aName) { this.aName = aName; } public B getbObject() { return bObject; } public void setbObject(B bObject) { this.bObject = bObject; } public A deepClone() { ByteArrayInputStream bis = null; ObjectInputStream ois = null; ByteArrayOutputStream bos = null; ObjectOutputStream oos = null; try { //序列化 bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(this); //反序列化 bis = new ByteArrayInputStream(bos.toByteArray()); ois = new ObjectInputStream(bis); A o = (A) ois.readObject(); return o; } catch (Exception e) { e.printStackTrace(); return null; } finally { //从下往上关闭流 try { ois.close(); bis.close(); oos.close(); bos.close(); } catch (IOException e) { e.printStackTrace(); } } } }