目录
原型模式:
指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
简单的来说就是 实体类 的复制操作。(在复制成百上千个时候,并且类的属性比较多的时候,会比较麻烦,原型模式能很好的解决这种问题。)
主对象:
import java.io.*;
/**
* 原型模式
* Create by yang_zzu on 2020/7/8 on 19:19
*/
public class Product implements Cloneable,Serializable {
private static final long serialVersionUID = -2701668816333438049L;
private String part1;
private String part2;
private Integer part3;
private Integer part4;
private BaseInfo baseInfo;
public String getPart1() {
return part1;
}
public void setPart1(String part1) {
this.part1 = part1;
}
public String getPart2() {
return part2;
}
public void setPart2(String part2) {
this.part2 = part2;
}
public Integer getPart3() {
return part3;
}
public void setPart3(Integer part3) {
this.part3 = part3;
}
public Integer getPart4() {
return part4;
}
public void setPart4(Integer part4) {
this.part4 = part4;
}
public BaseInfo getBaseInfo() {
return baseInfo;
}
public void setBaseInfo(BaseInfo baseInfo) {
this.baseInfo = baseInfo;
}
public Product() {
}
public Product(String part1, String part2, Integer part3, Integer part4, BaseInfo baseInfo) {
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
this.part4 = part4;
this.baseInfo = baseInfo;
}
@Override
public String toString() {
return super.hashCode()+"}Product{" +
"part1='" + part1 + '\'' +
", part2='" + part2 + '\'' +
", part3=" + part3 +
", part4=" + part4 +
", baseInfo=" + baseInfo +
'}';
}
/**
* 浅拷贝
*
* @return
* @throws CloneNotSupportedException
*/
/*@Override
protected Product clone() throws CloneNotSupportedException {
return (Product) super.clone();
}*/
/**
* 深拷贝
*
* 递归实现 Cloneable 的 clone 方法
* @return
* @throws CloneNotSupportedException
*/
/*@Override
protected Product clone() throws CloneNotSupportedException {
BaseInfo clone = this.baseInfo.clone();
Product product = (Product) super.clone();
product.setBaseInfo(clone);
return product;
}*/
/**
* 序列化深拷贝
*
* 通过序列化的方式进行拷贝,在解析数据流的时候,需要CPU的参与,消耗资源比较多
* 不建议使用这种方式
* 类及子类,都需要实现 Cloneable,Serializable 并且赋予 UUID
*/
@Override
protected Product clone() throws CloneNotSupportedException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
Product object = (Product) objectInputStream.readObject();
return object;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
子对象:
import java.io.Serializable;
/**
* Create by yang_zzu on 2020/7/8 on 19:32
*/
public class BaseInfo implements Cloneable, Serializable {
private static final long serialVersionUID = -9149578440105162389L;
private String companyName;
public BaseInfo(String companyName) {
this.companyName = companyName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
@Override
public String toString() {
return super.hashCode()+"}BaseInfo{" +
"companyName='" + companyName + '\'' +
'}';
}
@Override
protected BaseInfo clone() throws CloneNotSupportedException {
return (BaseInfo) super.clone();
}
}
测试方法:
/**
* Create by yang_zzu on 2020/7/8 on 19:21
*/
public class PrototyTest {
public static void main(String[] args) throws CloneNotSupportedException {
BaseInfo baseInfo = new BaseInfo("1234");
Product product = new Product("part1", "part2", 3, 4,baseInfo);
System.out.println(product);
//实现浅拷贝(继承Cloneable 重写 clone 方法)
Product clone = product.clone();
System.out.println(clone);
product.setPart4(40);
product.getBaseInfo().setCompanyName("xxxxx");
// baseInfo.setCompanyName("xxxxx");
System.out.println(product);
System.out.println(clone);
}
}
浅拷贝:
通过打印出来的 hashCode 可以看到,对象里面嵌套的其他对象是公用的,所以在修改嵌入的对象的数据之后,拷贝后的新对象的嵌入对象的值也会发生改变。
像 integer , string , double, boolean 等8中原生的数据类型,是不会被修改的,也就是拷贝后是一个新的对象,和原对象没有任何关系。
这种拷贝的方式是浅拷贝。
深拷贝:
解决方式,将引入的其他对象也继承 Cloneable 方式,实现 clone 方法。然后在原对象克隆的时候,再手动的对 引入的对象进行clone 操作,然后再放到原对象克隆之后的对象中。
序列化深拷贝:
===========================================================================
所有数组均被视为实现了{@code Cloneable}接口,并且数组类型{@code T []}
这个意思表达的是,对象里面如果有数组要进行手的 拷贝 操作,即数据实现的是浅拷贝。
ArrayList 实现的是浅拷贝,不会拷贝,里面的对象
AbstractBeanDefinition 中使用的clone 方式是自己定义,使用的是 set 方法,一个一个进行赋值的。
最终调用的是 AbstractBeanDefinition 方法