创建者模式 -- 原型模式

本文深入探讨了Java中对象克隆的实现方式,包括浅克隆和深克隆的区别及其实现方法。通过实例展示了如何实现Cloneable接口并重写clone方法进行浅克隆,以及如何通过序列化和反序列化实现深克隆,确保对象及其引用类型的完全独立。

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

要实现克隆要实现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());
    }
}

结果:

 

转载于:https://www.cnblogs.com/DDiamondd/p/10969512.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值