定义:用原型实例创建指定的创建对象的种类,并通过拷贝这些原型对象创建新的对象
应用场景:1.一般情况下用来保护原型对象不收侵犯。
2.类初始化需要消耗许多的资源,可以通过原型拷贝避免消耗这些资源。
3.通过new一个对象需要非常繁琐的数据准备和访问的权限。
注意的情景:拷贝分为浅拷贝和深拷贝。
在 Java 中数据类型可以分为两大类:基本类型和引用类型。
基本类型也称为值类型,分别是字符类型 char,布尔类型 boolean以及数值类型 byte、short、int、long、float、double。
引用类型则包括类、接口、数组、枚举等。
Java 将内存空间分为堆和栈。基本类型直接在栈中存储数值,而引用类型是将引用放在栈中,实际存储的值是放在堆中,通过栈中的引用指向堆中存放的数据。
所以当时基本类型时,克隆之后的值还是在栈中,但是引用数据类型具体的值时在堆中,但是具体的引用的地址还是在栈中,当AB同时引用一个地址时,A改变引用地址的值,B也跟着改动,B改动A也跟着改动,所以造成了B对象克隆了A对象之后,B对象修改具体的值,造成了A对象的值也发生变化所以不满足原型模式的要求了。
所以对应的解决方法就是深拷贝,也就是将引用对象的所以属性复制一份,包括栈的地址和对应对堆的值。
实现深拷贝的方式:
1.使引用类型的所有属性进行clone
2.可以通过序列化,序列化是将对象写到流中便于传输,而反序列化则是把对象从流中读取出来。这里写到流中的对象则是原始对象的一个拷贝,因为原始对象还存在 JVM 中,所以我们可以利用对象的序列化产生克隆对象,然后通过反序列化获取这个对象。
具体的代码如下:
先写一个原型的类BeanTest:
public class BeanTest implements Cloneable { private String name; private String content; private ArrayList
具体使用的时候Client代码如下:
public class Client { public static void main(String[] args) throws CloneNotSupportedException { BeanTest beanTest1 = new BeanTest(); beanTest1.setName("小"); beanTest1.setContent("1"); beanTest1.addList("q"); beanTest1.addList("s"); beanTest1.show(); BeanTest beanTest2 = beanTest1.clone(); beanTest2.show(); beanTest2.setName("大"); beanTest2.setContent("3"); beanTest2.addList("f"); beanTest2.show(); beanTest1.show(); } }
运行结果如下:name小
content1
q
s
name小
content1
q
s
name大
content3
q
s
f
name小
content1
q
s
原型模式的总结:
原型模式本质上就是对象拷贝,容易出现的问题就是深拷贝和浅拷贝。比较重要的特性就是,保护原型对象属性不受侵害,避免频繁的new对象,节约资源消耗。
注意点:直接拷贝对象的化,也就是clone对象的化,是不会走构造函数的,这个点需要注意



