ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

6.原型模式prototype

2021-04-18 17:35:42  阅读:109  来源: 互联网

标签:Product name product 模式 hashcode 原型 date prototype public


该模式的作用就是复制对象,特别是复杂的对象。

1.浅克隆

两个要点:实现Cloneable接口,重写clone()方法

public class Product implements Cloneable{

  private String name;
  private Date date;

  public Product(String name, Date date) {
    this.name = name;
    this.date = date;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Date getDate() {
    return date;
  }

  public void setDate(Date date) {
    this.date = date;
  }

  @Override
  public String toString() {
    return "Product{" +
        "name='" + name + '\'' +
        ", date=" + date +
        '}';
  }

  @Override
  protected Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
}  

测试结果:

//浅克隆
  public static void main(String[] args) throws CloneNotSupportedException {
    Date date1 = new Date();
    Product product = new Product("张三",date1);
    System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());

    Product cloneProduct = (Product) product.clone();
    System.out.println("v2=>"+cloneProduct+" hashcode=>"+cloneProduct.hashCode());

    date1.setTime(22223333);
    System.out.println("===========修改属性后========");

    System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
    System.out.println("v2=>"+cloneProduct+" hashcode=>"+cloneProduct.hashCode());
  }

  打印结果:

v1=>Product{name='张三', date=Sun Apr 18 16:45:56 CST 2021} hashcode=>1836019240
v2=>Product{name='张三', date=Sun Apr 18 16:45:56 CST 2021} hashcode=>325040804
===========修改属性后========
v1=>Product{name='张三', date=Thu Jan 01 14:10:23 CST 1970} hashcode=>1836019240
v2=>Product{name='张三', date=Thu Jan 01 14:10:23 CST 1970} hashcode=>325040804

  结论:原对象和克隆对象的date属性是同一个

2.深克隆

解决上个案例中date属性指向同一个问题。

public class Product implements Cloneable{

  private String name;
  private Date date;

  public Product(String name, Date date) {
    this.name = name;
    this.date = date;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Date getDate() {
    return date;
  }

  public void setDate(Date date) {
    this.date = date;
  }

  @Override
  public String toString() {
    return "Product{" +
        "name='" + name + '\'' +
        ", date=" + date +
        '}';
  }

  @Override
  protected Object clone() throws CloneNotSupportedException {
    Product product = (Product)super.clone();
    product.date = (Date) this.date.clone();
    return product;
  }
}

  测试结果

//深克隆
  public static void main(String[] args) throws CloneNotSupportedException {
    Date date1 = new Date();
    Product product = new Product("张三",date1);
    System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());

    Product cloneProduct = (Product) product.clone();
    System.out.println("v2=>"+cloneProduct+" hashcode=>"+cloneProduct.hashCode());

    date1.setTime(22223333);
    System.out.println("===========修改属性后========");

    System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
    System.out.println("v2=>"+cloneProduct+" hashcode=>"+cloneProduct.hashCode());
  }

  打印:

v1=>Product{name='张三', date=Sun Apr 18 16:56:55 CST 2021} hashcode=>1836019240
v2=>Product{name='张三', date=Sun Apr 18 16:56:55 CST 2021} hashcode=>325040804
===========修改属性后========
v1=>Product{name='张三', date=Thu Jan 01 14:10:23 CST 1970} hashcode=>1836019240
v2=>Product{name='张三', date=Sun Apr 18 16:56:55 CST 2021} hashcode=>325040804

  结论:实现的深克隆,date对象也成功克隆,这里有个前提,Date类也实现了Cloneable接口才行。

3.通过序列化来复制对象

深度克隆有个问题:所有属性都要克隆,属性下面可能还有属性,需要层层克隆,非常麻烦,通过流来复制可以减少这些麻烦,但是IO流会增加系统消耗。

前提是被序列化的对象实现Serializable接口,包括它的层层下面的属性,如果某个属性不想序列化,可以通过一些注解来忽略。

public class Product implements Serializable {

  private String name;
  private Date date;

  public Product(String name, Date date) {
    this.name = name;
    this.date = date;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Date getDate() {
    return date;
  }

  public void setDate(Date date) {
    this.date = date;
  }

  @Override
  public String toString() {
    return "Product{" +
        "name='" + name + '\'' +
        ", date=" + date +
        '}';
  }
}

  测试代码

public class CloneObject {

  public static void main(String[] args) {
    Date date1 = new Date();
    Product product = new Product("张三",date1);
    System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());

    Product product1 = cloneUtil.cloneObject(product);
    System.out.println("v2=>"+product1 +" hashcode=>"+product1.hashCode());

    date1.setTime(22223333);
    System.out.println("===========修改属性后========");
    System.out.println("v1=>"+product +" hashcode=>"+product.hashCode());
    System.out.println("v2=>"+product1 +" hashcode=>"+product1.hashCode());


  }
}
class cloneUtil {
  private cloneUtil() {
  }

  @SuppressWarnings("unchecked")
  public static <T extends Serializable> T cloneObject(T obj) {
    T cloneObj = null;

    // 序列化
    ByteArrayOutputStream bout = null;
    ObjectOutputStream oos = null;
    try {
      bout = new ByteArrayOutputStream();
      oos = new ObjectOutputStream(bout);
      oos.writeObject(obj);
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      close(oos);
      close(bout);
    }

    // 反序列化
    ByteArrayInputStream bin = null;
    ObjectInputStream ois = null;
    try {
      bin = new ByteArrayInputStream(bout.toByteArray());
      ois = new ObjectInputStream(bin);
      cloneObj = (T) ois.readObject();
    } catch (IOException | ClassNotFoundException e) {
      e.printStackTrace();
    } finally {
      close(ois);
      close(bin);
    }

    return cloneObj;
  }

  private static void close(Closeable closeable) {
    if (closeable != null) {
      try {
        closeable.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}

  打印结果:

v1=>Product{name='张三', date=Sun Apr 18 17:03:19 CST 2021} hashcode=>1836019240
v2=>Product{name='张三', date=Sun Apr 18 17:03:19 CST 2021} hashcode=>1072408673
===========修改属性后========
v1=>Product{name='张三', date=Thu Jan 01 14:10:23 CST 1970} hashcode=>1836019240
v2=>Product{name='张三', date=Sun Apr 18 17:03:19 CST 2021} hashcode=>1072408673

  

标签:Product,name,product,模式,hashcode,原型,date,prototype,public
来源: https://www.cnblogs.com/johnzhao/p/14673947.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有