原型模式

原型模式

学习自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;
}

posted @ 2020-06-06 11:14  MrHanhan  阅读(160)  评论(0编辑  收藏  举报