在本节中,咱们将学习和使用原型模式;这一节学习的原型模式也是建立型
模式的其中之一。再次复习一下:建立型
模式就是描述如何去更好的建立一个对象。html
咱们都知道,在JAVA 语言中。使用new
关键字建立一个新对象。将新的对象放到堆内存
里面。固然,这个内存确定是有大小限制的,何况,JAVA 不一样于C语言等。 有内存管理机制,就是咱们常说的垃圾回收器GC
,才能够保证内存不被溢出。java
说这些其实就是为了表示:为啥要用单例模式,能节省内存的时候,能用一个对象解决重复的事情,绝对不会建立多个。git
原型模式描述的如何快速建立重复的对象,而且减小new 关键字的使用。数据库
容我来一个一个解释:数组
抽象原型类 也就是咱们具体要实现的某个类,这个类在JAVA 里面是有具体的接口的,实际上是一个空接口,Cloneable
学习
* @author unascribed * @see java.lang.CloneNotSupportedException * @see java.lang.Object#clone() * @since JDK1.0 */ public interface Cloneable { }
咱们会发现,这个类没有任何的方法,怎么来实现它,不要慌。先接着走。.net
具体原型类 也就是咱们具体要克隆
的对象。好比咱们重复的要建立100个学生Student
对象,那么具体的学生对象就是具体原型类
code
public class Student implements Cloneable { private int id; private String name; private int sex; }
访问类 我就没必要多说了htm
原型模式其实也分浅克隆和深克隆。如何理解这两个概念呢?对象
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进行回收,那么这个对象的任何属性都是消失,咱们能不能找一个方法,将内存中这种对象的属性以及对象的状态经过某种东西保存下来,好比保存到数据库,下次从数据库将这个对象还原
到内存里面。 这就是序列化。
内存对象->序列字符
序列字符->内存对象
* @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