创建者模式 -- 原型模式

以某个对象为原型,克隆出新的对象。克隆出的新对象不会影响原型对象。

要实现克隆要实现Cloneable接口和clone()方法

注意:clone() 是Object类的本地方法(效率高)

Cloneable只是一个空接口,但是想要克隆,必须实现Cloneable接口

public interface Cloneable {
}

 

栗子:

public class People implements Cloneable {
    private Date birthday;
    private String name;

    @Override
    protected People clone() throws CloneNotSupportedException {
        People p = (People) super.clone();
        return p;
    }

    public People(Date d, String name){
        birthday = d;
        this.name = name;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
class Test{
    public static void main(String[] args) throws CloneNotSupportedException {
        Date d = new Date(1234567897);
        People p1 = new People(d, "张三");

        People p2 = p1.clone();
        System.out.println(p1 == p2); //false 克隆出一个新的对象
        System.out.println(p1.getBirthday());
        System.out.println(p2.getBirthday());  // 两个值完全相同
    }
}

这种克隆属于浅克隆:

仅仅把原型对象的值全部克隆给新对象,包括原型对象的一些引用地址(克隆过后,新/原型对象的引用地址指向同一个地址)

 

深克隆:连同属性也一起克隆

@Override
    protected People clone() throws CloneNotSupportedException {
        People p = (People) super.clone();
        p.birthday = (Date) this.birthday.clone();
        return p;
    }

利用序列化和反序列化 实现深克隆:

class Test{
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        Date d = new Date(1234567897);
        People p1 = new People(d, "张三");

        //序列化
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(p1);
        byte[] bytes = bos.toByteArray();  //这个字节数组里面有对象的状态和对象属性的值
        oos.close();
        bos.close();
        //反序列化
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);
        People p2 = (People) ois.readObject();


        System.out.println(p1.getBirthday());
        System.out.println(p2.getBirthday());
        //修改原型对象的属性
        p1.setBirthday(new Date(987654321));
        System.out.println(p1.getBirthday());
        System.out.println(p2.getBirthday());
    }
}

结果:

 

posted @ 2019-06-03 19:19  DDiamondd  阅读(247)  评论(0编辑  收藏  举报
TOP