原型模式
原型模式
学习自B站遇见狂神说
原型模式属于对象的创建模式。通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。这就是原型模式的用意。
浅克隆
如果是引用类型只是克隆了对象的引用,没有克隆对象的属性。看代码中出现的问题
/**
* @author M.han
*原型,继承Cloneable,实现Clone方法
*/
public class Person implements Cloneable{
private String name;
private Date birthday;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();//是一个本地方法
}
//get、set、等略
}
//测试类
Date date = new Date();
Person p1 = new Person("韩韩1", date);
Person p2 = (Person) p1.clone();
System.out.println(p1+"p1----->"+p1.hashCode());
System.out.println(p2+"p2----->"+p2.hashCode());
date.setTime(121212323);
System.out.println(p1+"p1----->"+p1.hashCode());
System.out.println(p2+"p2----->"+p2.hashCode());
结果:发现两个对象的birthday都被修改了,因为这个属性是引用类型的。
深克隆
对clone方法进行处理,对引用类型的属性也进行克隆。
@Override
protected Object clone() throws CloneNotSupportedException {
//将这个对象的birthday属性月进行克隆也进行克隆
Person obj = (Person) super.clone();
obj.birthday = (Date) this.birthday.clone();
return obj;
}
运行结果:没有改变p2的属性。
序列化实现深克隆
实现Serializeble接口
public Object deepCone(){
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
Person person = null;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// System.out.println("write成功!");
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
person = (Person) ois.readObject();
}catch (Exception e){
System.out.println("错误:"+e.getMessage());
}finally {
try {
if (ois!= null){
ois.close();
}
if (bis!= null){
bis.close();
}
if (oos!= null){
oos.close();
}
if (bos!= null){
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return person;
}