IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 设计模式-原型模式 -> 正文阅读

[Java知识库]设计模式-原型模式

定义

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

模式的角色和类图

原型模式包含如下角色:

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

类图

在这里插入图片描述

Cloneable接口只是一个标识,接口里面并没有任何方法。真正的clone方法在Object类中。

实现

具体代码如下:

public class User implements Cloneable, Serializable {
    private Person person;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public User(){
        System.out.println("原型对象创建完成");
    }
    @Override
    protected User clone() throws CloneNotSupportedException {
        return (User)super.clone();
    }
    public void show(){
        System.out.println("用户"+person.getName()+"正在工作!");
    }
}
public class Person implements Serializable {
    private String name;

    public Person(String name){
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

使用测试代码测试:

public class MainTest {
    public static void main(String[] args) throws Exception {
        User user = new User();
        Person person = new Person("张三");
        user.setPerson(person);
        User user1 = user.clone();
        System.out.println(user1 == user);
        System.out.println(user1.getPerson() == user.getPerson());
    }
}

结果:

原型对象创建完成
false
true

所以使用Obeject中的克隆方法得到的对象时一个新的对象。但是对象中的非基本类型属性是相等的,并没有重新创建。这就引出了原型模式的深拷贝浅拷贝

浅拷贝和深拷贝

定义

  • 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
  • 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

所以如果只是实现Object中的Clone方法后也没有重写,那么就是浅拷贝,对象中非基本类型的属性没有重新创建新对象。如果需要一个新的属性对象。可以重写clone方法。创建新的属性对象。这就是深拷贝
如实现深拷贝,可将clone方法重写,具体代码如下:

 @Override
    protected User clone() throws CloneNotSupportedException {
        User user = (User)super.clone();
        user.setPerson(new Person("新对象"));
        return user;
    }

测试结果:

原型对象创建完成
false
false

还有一种深拷贝就是通过对象流的方式读取已经写入文件中的对象。在单列模式中我们说到对象流对单列模式的破坏是一个道理。在没有readResovle方法的情况下,对象流读取对象时会返回一个全新的对象,并且是深拷贝后的对象,我们通过代码测试下。
具体代码如下:

public class MainTest {
    public static void main(String[] args) throws Exception {
        User user = new User();
        Person person = new Person("张三");
        user.setPerson(person);


        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\lenovo\\Desktop\\cs.txt"));
        oos.writeObject(user);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\lenovo\\Desktop\\cs.txt"));
        User user1 = (User)(ois.readObject());
        ois.close();

        System.out.println(user.getPerson() == user1.getPerson());
        user.show();
        user1.getPerson().setName("李四");
        user1.show();


    }
}

结果:

原型对象创建完成
false
用户张三正在工作!
用户李四正在工作!

上述代码没有调用clone方法。就是通过对象流的readObject(),我们得到的结果是原型对象创建了,并且非基本类型属性也重新创建了。这就是深拷贝

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章           查看所有文章
加:2021-10-07 13:43:18  更:2021-10-07 13:45:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:00:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码