在本节中,我们将学习和使用原型模式;这一节学习的原型模式也是创建型 模式的其中之一。再次复习一下:创建型 模式就是描述如何去更好的创建一个对象。

我们都知道,在JAVA 语言中。使用new 关键字创建一个新对象。将新的对象放到堆内存 里面。当然,这个内存肯定是有大小限制的,况且,JAVA 不同于C语言等。 有内存管理机制,就是我们常说的垃圾回收器GC,才可以保证内存不被溢出。

说这些其实就是为了表示:为啥要用单例模式,能节省内存的时候,能用一个对象解决重复的事情,绝对不会创建多个。

概述

原型模式描述的如何快速创建重复的对象,并且减少new 关键字的使用。

  • 抽象原型类
  • 具体原型类
  • 访问类

容我来一个一个解释:

抽象原型类 也就是我们具体要实现的某个类,这个类在JAVA 里面是有具体的接口的,其实是一个空接口,Cloneable

 * @author  unascribed
* @see java.lang.CloneNotSupportedException
* @see java.lang.Object#clone()
* @since JDK1.0
*/
public interface Cloneable {
}

我们会发现,这个类没有任何的方法,怎么来实现它,不要慌。先接着走。

具体原型类 也就是我们具体要克隆 的对象。比如我们重复的要创建100个学生Student 对象,那么具体的学生对象就是具体原型类

public class Student implements Cloneable {

    private int id;

    private String name;

    private int sex;
}

访问类 我就不必多说了

浅克隆和深克隆

原型模式其实也分浅克隆和深克隆。如何理解这两个概念呢?

浅克隆

protected native Object clone() throws CloneNotSupportedException;

浅克隆,只需要具体原型类 实现Cloneable 接口,并且重写父类Object类的clone() 方法,即可实现对象的浅克隆。

Student student1 = new Student(1, "李四");
Student student2 = student1.clone(); System.out.println(student1);
System.out.println(student2); System.out.println(student1 == student2);
---------------------
学号:1,姓名:李四
学号:1,姓名:李四
false
  • 通过执行clone() 方法即可创建一个相同的,具有同样属性的对象。
  • 并且是新的对象,内存地址有所不同。

我们来看看,对于引用类型的变量,浅克隆是否可以进行克隆;

Teacher teacher = new Teacher(1, "张老师");

Student student1 = new Student(1, "李四", teacher);
Student student2 = student1.clone(); System.out.println(student1);
System.out.println(student2); System.out.println(student1 == student2);
------------
学号:1,姓名:李四,老师=Teacher@1b6d3586
学号:1,姓名:李四,老师=Teacher@1b6d3586
false

我们发现,引用类型并没有被克隆,也就是说:

特点

  • 浅克隆对于基本类型,可以进行完全的克隆,并且克隆的对象是一个新的对象
  • 但是对象里面的引用,是无法被克隆的。

深克隆(序列化)

何谓序列化?

我们创建的都是保存在内存里面的,只要被虚拟机GC进行回收,那么这个对象的任何属性都是消失,我们能不能找一个方法,将内存中这种对象的属性以及对象的状态通过某种东西保存下来,比如保存到数据库,下次从数据库将这个对象还原到内存里面。 这就是序列化。

  • 序列化 内存对象->序列字符
  • 反序列化 序列字符->内存对象

请参考: https://baike.baidu.com/item/序列化/2890184

JAVA 序列化

 * @see java.io.Externalizable
* @since JDK1.1
*/
public interface Serializable {
}

JAVA 提供了一个空接口,其实这个接口和上面的Cloneable 一样,都是一个空接口,其实这个空接口就是作为一种标识 你的对象实现了这个接口,JAVA 认为你的这个就可以被序列化 ,就是这么简单。

Teacher teacher = new Teacher(1, "张老师");

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream stream = new ObjectOutputStream(outputStream); stream.writeObject(teacher);
System.out.println(Arrays.toString(outputStream.toByteArray()));
----------
[-84, -19, 0, 5, 115, 114, 0, 7, 84, 101, 97,。。。。。。

通过将对象序列化、其实也就是将内存中的对象转化为二进制 字节数组

反序列化

Teacher teacher = new Teacher(1, "张老师");
System.out.println(teacher); ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream stream = new ObjectOutputStream(outputStream); stream.writeObject(teacher);
System.out.println(Arrays.toString(outputStream.toByteArray())); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray());
ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream); Teacher teacher1 = (Teacher) inputStream.readObject();
System.out.println(teacher1);
---------------
id=1,name=张老师
[-84, -19, 0, 5, 115, xxxxx,-127, -27, -72, -120]
id=1,name=张老师

通过序列化和反序列化,即可对象的深克隆

小结

这一节,在讲述 原型模式的同时,将原有实现原型模式的clone() 浅克隆,延伸到深克隆这一概念。其实JAVA 的原型模式,实现起来较为简单。但还是要按需要实现,Object 类提供的 clone 浅克隆 是没办法克隆对象的引用类型的。需要克隆引用类型,还是需要序列化 深克隆

参考

http://c.biancheng.net/view/1343.html

https://www.liaoxuefeng.com/wiki/1252599548343744/1298366845681698

代码示例

https://gitee.com/mrc1999/Dev-Examples

欢迎关注

最新文章

  1. Android斗地主棋牌游戏牌桌实现源码下载
  2. 51nod算法马拉松12
  3. 每日一九度之 题目1040:Prime Number
  4. Mysql-学习笔记(==》建表修改一)
  5. java中类名.class、实例.getclass()区别
  6. Android 框架简介--Java环境(转)
  7. HDU5828 Rikka with Sequence 线段树
  8. 关于HTML与CSS编写规范
  9. PNG优化/压缩
  10. 重新温习,不但可以让自己对js更加的深刻认识,又能加深记忆,至此每天一次复习记录在此。
  11. [Java] Java IO Files
  12. [ExtJS5学习笔记]第22 Extjs5正在使用beforeLabelTpl添加所需的配置选项标注星号标记
  13. 扔鸡蛋问题详解(Egg Dropping Puzzle)
  14. 洛谷-生活大爆炸版石头剪刀布-NOIP2014提高组复赛
  15. 获取Excel部分数据并很据项目要求计算适宜性等级综合指数判断该地区的土壤适宜性
  16. iOS 插件化开发汇总 Small框架
  17. Asp.Net Core 基于QuartzNet任务管理系统
  18. sleep()和wait()的区别及wait方法的一点注意事项
  19. phpcms列表页替换
  20. MySql:SELECT 语句(一)基本查询

热门文章

  1. 读Pyqt4教程,带你入门Pyqt4 _012
  2. Chisel3 - util - MixedVec
  3. Shell脚本 (三) 条件判断 与 流程控制
  4. Java实现 蓝桥杯VIP 算法训练 Hanoi问题
  5. Java实现 LeetCode 274 H指数
  6. Java实现 LeetCode 144 二叉树的前序遍历
  7. Java实现 蓝桥杯 算法提高 最大值路径
  8. Android studio环境配置(运行报错)
  9. 树莓派使用 OLED 屏显示图片及文字
  10. Java基础(九)