定义
原型模式是用于创建重复的对象 ,同时又能保证性能。
意图: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
实现方式 主要有两种情况:一种是浅克隆 ;一种是深克隆 。
浅克隆 主要理解: 创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
前提: 实现Cloneable接口
关键代码: 重写Object对象的clone()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import java.util.Date;public class Person implements Cloneable { private String name; private int age; private Date birthday; @Override protected Object clone () throws CloneNotSupportedException { return super .clone(); } public static void main (String[] args) throws CloneNotSupportedException { Person person = new Person(); Person person1 = (Person) person.clone(); System.out.println(person == person1); } }
深克隆 主要理解: 创建一个新对象,属性中的引用的其他对象也会被克隆,不再指向原有对象的地址
重写clone()方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import java.util.Date;public class Person implements Cloneable { private String name; private int age; public Date getBirthday () { return birthday; } public void setBirthday (Date birthday) { this .birthday = birthday; } private Date birthday; @Override protected Object clone () throws CloneNotSupportedException { Person person = null ; person = (Person) super .clone(); if (this .getBirthday() != null ) { person.setBirthday((Date) this .getBirthday().clone()); } return person; } }
通过重写clone方法,将对象中非基本类型属性也clone一下 (如果非基本类型属性是一个对象,且其还有其他非基本类型属性,则需继续将非基本类型属性的clone方法也进行重写,即“套娃”)
前提: 被序列化和反序列化的类需要实现Serializable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package com;import java.io.*;import java.util.Date;public class Person implements Serializable { private String name; private int age; public Date getBirthday () { return birthday; } public void setBirthday (Date birthday) { this .birthday = birthday; } private Date birthday; public static void main (String[] args) throws IOException, ClassNotFoundException { Person person = new Person(); Person person1 = (Person) Util.clone(person); System.out.println(person1); } } class Util { public static Object clone (Object obj) throws IOException, ClassNotFoundException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(stream); objectOutputStream.writeObject(obj); ByteArrayInputStream inputStream = new ByteArrayInputStream(stream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); Object object = objectInputStream.readObject(); return object; } }
上述序列化和反序列化的实现操作,可以放在单独的工具类中,也可以放在clone方法中(但这样需要实现Cloneable接口)
其中,如果对象由非基本类型属性,则非基本类型属性也需要实现Serializable接口
应用场景
资源优化场景
类初始化需要小号非常多的资源(包括数据、硬件资源等)
性能和安全要求的场景
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
一个对象多个修改这的场景
实际项目中,原型模式很少单独出现,一般是和工厂模式一块出现:通过clone方法创建一个对象,然后由工厂方法提供给调用者使用
补充:Object类的clone方法为什么一定要实现Cloneable接口? 我们看官方对Object类的clone方法的说明:
翻译后:
我的理解: clone方法是在Cloneable接口中声明的,但是Object类本身没有实现这个接口,所以如果直接调用Object的clone方法(不继承Cloneable接口),则会包运行时异常CloneNotSupportedException。
在Cloneable接口中也有明确说明,翻译后: