Java设计模式中原型模式是啥/浅克隆与深克隆又是什么/clone方法怎么回事

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库Java设计模式克隆下载学习使用!

4.5 原型模式

4.5.1 概述

用已创建实例作为原型,通过复制该原型对象来创建一个和原型对象一样的新对象

4.5.2 结构

  • 抽象原型类:规定具体原型对象必须实现的clone()方法
  • 具体原型类:实现抽象原型类中方法,是可被复制对象
  • 访问类:使用具体原型类中clone方法来复制新对象

4.5.3 分类

  • 浅克隆:创建对象,新对象属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向对象内存地址
  • 深克隆:创建对象,属性中引用其他对象会被克隆,不再指向原有对象地址
  1. Java中的Object类提供clone()方法实现浅克隆
  2. Java 中的 Cloneable 接口是抽象原型类,而实现了 Cloneable 接口的子实现类就是具体的原型类

4.5.4 验证浅克隆

  • 验证Object类clone()实现浅克隆
  • 具体原型
public class RealizeType implements Cloneable{  
    public RealizeType(){  
        System.out.println("具体原型创成功");  
    }  
    @Override  
    public RealizeType clone() throws CloneNotSupportedException {  
        System.out.println("克隆具体原型成功!");  
        return (RealizeType) super.clone();  
    }  
}
  • 测试
    public static void main(String[] args) throws Exception {  
//        创建具体原型对象  
        RealizeType realizeType = new RealizeType();  
//        克隆  
        RealizeType clone = realizeType.clone();  
        System.out.println("原型对象与克隆对象是否是同一个对象?" + (realizeType == clone ));  
    }

结果符合预期
![[Pasted image 20221229214315.png]]
# 注意:
java.lang.object规范中对clone方法的约定

  1. 对任何的对象x,都有x.clone() !=x 因为克隆对象与原对象不是同一个对象
  2. 对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样
  3. 如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立

4.5.5 使用场景

  • 对象创建比较复杂,可用原型模式快速创建对象
  • 性能和安全要求高

4.5.6 案例

  • 学生类
public class Student{  
    private String name;  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
}
  • 引用类
public class Citation implements Cloneable {  
    private Student student;  
    public Student getStudent() {  
        return student;  
    }  
    public void setStudent(Student student) {  
        this.student = student;  
    }  
    @Override  
    public Citation clone() throws CloneNotSupportedException {  
        return (Citation) super.clone();  
    }  
    public void show()  
    {  
        System.out.println(student.getName() + "是好学生");  
    }
}
  • 测试结果如图
    ![[Pasted image 20221229223250.png]]
public static void main(String[] args) throws CloneNotSupportedException {  
    Citation citation = new Citation();  
    Student student = new Student();  
    student.setName("张三");  
    citation.setStudent(student);  
    Citation clone = citation.clone();  
    clone.getStudent().setName("李四");  
    citation.show();  
    clone.show();  
}

4.5.7 深克隆

5.7.1 序列化与反序列化
  • 使用浅克隆案例
  • 给Citation类和学生类实现序列化接口
  • 修改测试类
public static void main(String[] args) throws Exception {  
    Citation citation = new Citation();  
    Student student = new Student();  
    student.setName("张三");  
    citation.setStudent(student);  
    ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./b.txt"));  
    outputStream.writeObject(citation);  
    outputStream.close();  
    ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("./b.txt"));  
    Citation citation1 = (Citation) objectInputStream.readObject();  
    objectInputStream.close();  
    citation.show();  
    citation1.getStudent().setName("李四");  
    citation1.show();  
}

结果
![[Pasted image 20221229224947.png]]

5.7.2 重写clone方法
  • 重写Citation类方法
@Override  
public Citation1 clone() throws CloneNotSupportedException {  
    Student student1 = new Student();  
    student1.setName(student.getName());  
    Citation1 citation1 = new Citation1();  
    citation1.setStudent(student1);  
    return citation1; 
}
  • 测试
    ![[Pasted image 20221229230006.png]]
public static void main(String[] args) throws CloneNotSupportedException {  
    Citation1 citation = new Citation1();  
    Student student = new Student();  
    student.setName("张三");  
    citation.setStudent(student);  
    Citation1 clone = citation.clone();  
    clone.getStudent().setName("李四");  
    citation.show();  
    clone.show();  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值