原型模式
原型模式,指将一个对象作为原型,对其进行复制、克隆,产生一个和原对象属性相同的新对象。
普通模式复制对象
调用对象的 get/set 方法设置属性
public class Sheep { private String name; private int age; 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; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(1); Sheep sheep2 = new Sheep(); sheep2.setName(sheep.getName()); sheep2.setAge(sheep.getAge()); // 各属性相同,但对象的地址不同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); System.out.println("sheep:" + sheep.hashCode()); System.out.println("sheep2:" + sheep2.hashCode());
原型模式复制对象
public class Sheep implements Cloneable { private String name; private int age; 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; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() { Sheep sheep = null; try { sheep = (Sheep) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return sheep; } }
Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(1); Sheep sheep2 = (Sheep) sheep.clone(); // 各属性相同,但对象的地址不同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); System.out.println("sheep:" + sheep.hashCode()); System.out.println("sheep2:" + sheep2.hashCode());
浅拷贝
基本数据类型
当成员变量是基本数据类型,浅拷贝会直接进行值传递,将该属性值复制一份给新对象。
引用数据类型
当成员变量是引用数据类型,浅拷贝会进行引用传递,将该属性的引用地址复制一份给新对象。 此时,新对象和原型对象的成员变量指向同一个实例,在一个对象中修改这个成员变量,另一个对象也会受到影响。
浅拷贝使用默认的 clone() 方法实现。
public class Dog implements Cloneable { private String name; private int age; 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; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() { Dog dog = null; try { dog = (Dog) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return dog; } } public class Sheep implements Cloneable { private String name; private int age; private Dog friend; 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 Dog getFriend() { return friend; } public void setFriend(Dog friend) { this.friend = friend; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}'; } @Override protected Object clone() { Sheep sheep = null; try { sheep = (Sheep) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return sheep; } }
Dog friend = new Dog(); friend.setName("Tom"); friend.setAge(1); Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(2); sheep.setFriend(friend); Sheep sheep2 = (Sheep) sheep.clone(); // 属性值相同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); // 对象的地址不同 System.out.println("sheep.hashCode:" + sheep.hashCode()); System.out.println("sheep2.hashCode:" + sheep2.hashCode()); // 引用数据类型成员变量的地址相同 System.out.println("sheep.friend:" + sheep.getFriend().hashCode()); System.out.println("sheep2.friend:" + sheep2.getFriend().hashCode());
深拷贝
不论成员变量是基本数据类型还是引用数据类型,深拷贝都会复制一份新的给新对象。
实现方式 1:重写 clone() 实现深拷贝
public class Dog implements Cloneable { private String name; private int age; 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; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override protected Object clone() { Dog dog = null; try { dog = (Dog) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return dog; } } public class Sheep implements Cloneable { private String name; private int age; private Dog friend; 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 Dog getFriend() { return friend; } public void setFriend(Dog friend) { this.friend = friend; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}'; } @Override protected Object clone() { Sheep sheep = null; try { // 对基本数据类型的拷贝 sheep = (Sheep) super.clone(); // 对引用数据类型的拷贝;需要引用类型也实现 Cloneable 接口 sheep.friend = (Dog) friend.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return sheep; } }
Dog friend = new Dog(); friend.setName("Tom"); friend.setAge(1); Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(2); sheep.setFriend(friend); Sheep sheep2 = (Sheep) sheep.clone(); // 属性值相同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); // 对象的地址不同 System.out.println("sheep.hashCode:" + sheep.hashCode()); System.out.println("sheep2.hashCode:" + sheep2.hashCode()); // 引用数据类型成员变量的地址也不相同 System.out.println("sheep.friend:" + sheep.getFriend().hashCode()); System.out.println("sheep2.friend:" + sheep2.getFriend().hashCode());
实现方式 2:通过对象序列化实现深拷贝
public class Dog implements Serializable { private String name; private int age; 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; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } } // 所有相关对象都要实现 Serializable 接口,包括 Dog public class Sheep implements Serializable { private String name; private int age; private Dog friend; 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 Dog getFriend() { return friend; } public void setFriend(Dog friend) { this.friend = friend; } @Override public String toString() { return "Sheep{" + "name='" + name + '\'' + ", age=" + age + ", friend=" + friend + '}'; } // 通过对象的序列化实现深拷贝 public Object deepClone() { Sheep copySheep = null; ByteArrayOutputStream bos = null; ObjectOutputStream oos = null; ByteArrayInputStream bis = null; ObjectInputStream ois = null; try { // 序列化 // 把当前对象输出到流 bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(this); // 反序列化 // 从流中获取对象数据,并读取 bis = new ByteArrayInputStream(bos.toByteArray()); ois = new ObjectInputStream(bis); copySheep = (Sheep) ois.readObject(); } catch (IOException | SecurityException | NullPointerException | ClassNotFoundException e) { e.printStackTrace(); } finally { try { if (bos != null) { bos.close(); } if (oos != null) { oos.close(); } if (bis != null) { bis.close(); } if (ois != null) { ois.close(); } } catch (IOException e) { e.printStackTrace(); } } return copySheep; } }
Dog friend = new Dog(); friend.setName("Tom"); friend.setAge(1); Sheep sheep = new Sheep(); sheep.setName("Dolly"); sheep.setAge(2); sheep.setFriend(friend); Sheep sheep2 = (Sheep) sheep.deepClone(); // 属性值相同 System.out.println("sheep:" + sheep); System.out.println("sheep2:" + sheep2); // 对象的地址不同 System.out.println("sheep.hashCode:" + sheep.hashCode()); System.out.println("sheep2.hashCode:" + sheep2.hashCode()); // 引用数据类型成员变量的地址也不相同 System.out.println("sheep.friend:" + sheep.getFriend().hashCode()); System.out.println("sheep2.friend:" + sheep2.getFriend().hashCode());
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mkjdt/16290.html