关于java:Java设计模式原型模式

原型模式

用于克隆对象。

利用场景:

  1. 因为拷贝要比从新创立一个对象快得多,所以当创立一个对象所耗资源很多时,能够思考应用拷贝。
  2. 避免原对象被批改,例如在并发环境下的一个ArrayList,若须要批改其中的值又怕会引起并发批改异样,能够思考克隆后操作,即保护性拷贝。

浅拷贝

实现Cloneable接口,重写clone()办法。

 public class Sheep implements Cloneable{
  private String id;
  private String name;
  private int age;
  private Sheep friend;
 ​
  public Sheep() {
  }
 ​
  public Sheep(String id, String name, int age, Sheep friend) {
  this.id = id;
  this.name = name;
  this.age = age;
  this.friend = friend;
  }
 ​
  public String getId() {
  return id;
  }
 ​
  public void setId(String id) {
  this.id = id;
  }
 ​
  public String getName() {
  return name;
  }
 ​
  public void setName(String name) {
  this.name = name;
  }
 ​
  public int getAge() {
  return age;
  }
 ​
  public void setAge(int age) {
  this.age = age;
  }
 ​
  public Sheep getFriend() {
  return friend;
  }
 ​
  public void setFriend(Sheep friend) {
  this.friend = friend;
  }
 ​
  @Override
  public String toString() {
  return "Sheep{" +
  "id='" + id + ''' +
  ", name='" + name + ''' +
  ", age=" + age +
  ", friend=" + friend +
  '}';
  }
 ​
  @Override
  public Sheep clone() throws CloneNotSupportedException {
  return (Sheep) super.clone();
  }
 }

测试

 public class Main {
  public static void main(String[] args) throws CloneNotSupportedException {
  Sheep sheep = new Sheep();
  sheep.setAge(1);
  sheep.setName("teddy");
  sheep.setFriend(new Sheep("1","tom",1,null));
 ​
  Sheep cloneSheep=sheep.clone();
 ​
  System.out.println(sheep);
  System.out.println(cloneSheep);
 ​
  System.out.println(sheep.hashCode());
  System.out.println(cloneSheep.hashCode());
 ​
  System.out.println(sheep.getFriend().hashCode());//援用是同一个
  System.out.println(cloneSheep.getFriend().hashCode());
  }
 }

输入

 Sheep{id='null', name='teddy', age=1, friend=Sheep{id='1', name='tom', age=1, friend=null}}
 Sheep{id='null', name='teddy', age=1, friend=Sheep{id='1', name='tom', age=1, friend=null}}
 ​
 1956725890
 356573597
 ​
 1735600054
 1735600054

阐明浅拷贝无奈克隆援用。

深拷贝

一、应用clone()

同样实现Cloneable()接口,

将clone办法批改为

  @Override
  public Sheep clone(){
  Sheep sheep=null;
  try {
  sheep=(Sheep) super.clone();
  Sheep friendSheep = sheep.getFriend();
  if (friendSheep!=null){
  sheep.setFriend(friendSheep.clone());
  }
  } catch (CloneNotSupportedException e) {
  e.printStackTrace();
  }
  return sheep;
  }

留神:援用类型克隆前要判空。

测试输入:

 Sheep{id='null', name='teddy', age=1, friend=Sheep{id='1', name='tom', age=1, friend=null}}
 Sheep{id='null', name='teddy', age=1, friend=Sheep{id='1', name='tom', age=1, friend=null}}
 ​
 607635164
 529116035
 ​
 242481580
 1627800613
二、序列化
 public Sheep deepClone(){
  ByteArrayOutputStream out;
  ByteArrayInputStream in = null;
  ObjectInputStream oin = null;
  ObjectOutputStream oout=null;
  out = new ByteArrayOutputStream();
  try {
  oout=new ObjectOutputStream(out);
  oout.writeObject(this);
  //要保障out中有内容写入,不然会报EOFException
  in = new ByteArrayInputStream(out.toByteArray());
  oin=new ObjectInputStream(in);
  return (Sheep) oin.readObject();
  } catch (IOException | ClassNotFoundException e) {
  e.printStackTrace();
  }finally {
  try {
  if (oin!=null) {
  oin.close();
  }
  if (oout!=null){
  oout.close();
  }
  out.close();
  if (in != null) {
  in.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  }
  return null;
  }

流程:

  1. 实例化ByteArrayOutputStream;
  2. 实例化ObjectOutputStream;
  3. 写入对象
  4. 实例化ByteArrayInputStream
  5. 实例化ObjectInputStream
  6. 读出对象

留神:写入对象肯定要在实例化输出流之前,因为实例化ByteArrayInputStream传入输入流,以输入流中的内容读出对象,若输入流中没有内容,会在实例化ByteArrayInputStream时抛出EOFException。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理