Java设计模式之原型模式
1.关于原型模式的定义:原型模式属于对象的创建模式,是指通过给定的一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的方法创建出更多的同类型的对象。在java中简要 的可以理解为就是对已有对象的克隆,而对象的克隆可以分为浅克隆和深克隆。
2.浅克隆和深克隆的区别
浅克隆:拷贝原有对象的属性时,基本类型完全拷贝,引用类型拷贝的是引用的地址(即原有对象和拷贝对象引用的是同一个对象)。
深克隆:拷贝原有对象的属性时,基本类型和引用类型都会拷贝一份。
3.浅克隆和深克隆的实现
浅克隆最简单的实现方式就是重写object的clone方法,重写之前该类需要继承Cloneable接口,代码如下:
//1.继承Cloneable接口 public class User implements Cloneable{ private String name; private String gender; private List<Address> addressList; public User() { } public User(String name, String gender) { this.name = name; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public List<Address> getAddressList() { return addressList; } public void setAddressList(List<Address> addressList) { this.addressList = addressList; } //2.重写clone方法 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
深克隆的实现可以使用序列化的方式来实现,前提是需要克隆的类实现Serializable接口,代码如下:
//1.继承Cloneable接口 public class User implements Cloneable, Serializable { private String name; private String gender; private List<Address> addressList; public User() { } public User(String name, String gender) { this.name = name; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public List<Address> getAddressList() { return addressList; } public void setAddressList(List<Address> addressList) { this.addressList = addressList; } //2.重写clone方法 @Override protected Object clone() throws CloneNotSupportedException { //return super.clone(); return deepClone(this); } private Object deepClone(Object obj){ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(bos); oos.writeObject(obj); } catch (IOException e) { e.printStackTrace(); } finally { try { oos.close(); bos.close(); } catch (IOException e) { e.printStackTrace(); } } ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = null; Object result = null; try { ois = new ObjectInputStream(bis); result = ois.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { try { ois.close(); bis.close(); } catch (IOException e) { e.printStackTrace(); } } return result; } }