JAVA设计模式(原型链模式)

原型链模式是一个创建对象的模式。他利用克隆方法,将对象进行复制。这种复制又分为浅层复制合深层复制,他们之间的区别就在于,对有其他对象的引用时候,是否会创建副本。说起来不好理解,看一个例子就很好理解。

(一)浅层复制

//后面会引用的Person对象
public class Person implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

//必须实现Cloneable接口,否则会抛出 java.lang.CloneNotSupportedException
public class MyTest implements Cloneable{

    private Integer x = 10;

    private Person person;
public static void main(String[] args) throws CloneNotSupportedException {
        MyTest test1 = new MyTest();
        Person person = new Person();
        person.setName("浅层复制");
        test1.setPerson(person);
        MyTest test2 = (MyTest) test1.clone();
        System.out.println(test1.getX()+"                 "+test2.getX());
        System.out.println(test1.getPerson().getName()+"            "+test2.getPerson().getName());
        person.setName("pserson修改之后的名字");
        test1.setX(1);
        System.out.println(test1.getX()+"                 "+test2.getX());
        System.out.println(test1.getPerson().getName()+"            "+test2.getPerson().getName());
        System.out.println(test1.getPerson()+"            "+test2.getPerson());
    }

public Person getPerson() {
        return person;
    }
    public void setPerson(Person person) {
        this.person = person;
    }
    public Integer getX() {
        return x;
    }
    public void setX(Integer x) {
        this.x = x;
    }
打印结果
10                 10
浅层复制            浅层复制
1                 10
pserson修改之后的名字            pserson修改之后的名字
com.my.prototype.Person@1fb8ee3            com.my.prototype.Person@1fb8ee3
根据打印结果,复制一个对象之后,复制后的对象test2中的属性,和test1中的属性值时一样的。test1调用setX(1),将test1对象的x属性修改了,而test2的x值并没有发生变化,因为test1只是修改的它自己的属性。并且他们所引用的person对象都是同一个,所以当任何一个对象修改person属性的时候,只要引用了这个person地址的对象,都会发生变化。

(二)深层复制

深层复制时利用了IO来复制对象,这种复制就是将原来的对象的所有属性值再创建一遍。对于经过IO的类,必须序列化。
public class DeepClone implements Cloneable,Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private Integer x = 10;

    private Person person;

    public static void main(String[] args) throws CloneNotSupportedException {
        DeepClone clone1 = new DeepClone();
        Person person = new Person();
        person.setName("深层复制");
        clone1.setPerson(person);
        clone1.setX(22);
        DeepClone clone2 = (DeepClone) clone1.clone();
        System.out.println(clone1.getPerson()+"          "+clone2.getPerson());
        person.setName("修改之后的名字");
        System.out.println(clone1.getPerson().getName()+"          "+clone2.getPerson().getName());
        clone1.setX(2);
        System.out.println(clone1.getX()+"          "+clone2.getX());
    }

    //这里没写关流操作
    @Override
    protected Object clone() throws CloneNotSupportedException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = null;
        Object obj = null;
        try {
            out = new ObjectOutputStream(bos);
            out.writeObject(this);
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream in = new ObjectInputStream(bis);
            obj = in.readObject();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return obj;
    }
    public Integer getX() {
        return x;
    }

    public void setX(Integer x) {
        this.x = x;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }
}
打印结果
com.my.prototype.Person@69b332          com.my.prototype.Person@1bf216a
修改之后的名字          深层复制
2          22
由打印结果,可以看出对象在复制的时候,创建了一个person对象的副本,所以指向的地址不同,这项修改一个对象person属性的时候,另一个不会发生任何变化,两个对象之间就相互独立了。

根据这个例子可以理解为,当引用其他类对象的时候,深层复制的两个对象之间是相互独立的,没有任何联系。而浅层复制,就是共享引用的对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值