java实现深拷贝

我们经常会用到对象的拷贝,但是但是继承Cloneable重写clone实现的只是浅拷贝,那么什么是深拷贝,什么是浅拷贝呢。
拷贝就是设计模式中原型模式的一种体现,原型模式是内存二进制流的拷贝,要比new一个对象的性能好的多的多,特别是在for循环中产生大量对象时,原型模式能更好的体现其优点。
其实从内存方面来说简单一句话,就是看有没有开辟新的内存空间用于存储拷贝的对象,浅拷贝只是拷贝一份引用,而深拷贝重新开辟堆内存存储拷贝的数据,浅拷贝对于基本类型和字符串String类型有效,具体原因这里不展开。
下面看下效果

一,继承Cloneable重写clone方法

public class Attachment  implements Serializable{

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class YuelyLog implements Serializable,Cloneable {
    private Attachment attachment;
    private String name;
    private String date;

    @Override
    protected YuelyLog clone() throws CloneNotSupportedException {
        return (YuelyLog)super.clone();
    }

    public Attachment getAttachment() {
        return attachment;
    }

    public void setAttachment(Attachment attachment) {
        this.attachment = attachment;
    }

    public String getName() {
        return name;
    }

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

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }
}
 public static void main(String[] args) throws IOException, ClassNotFoundException, CloneNotSupportedException {
        Attachment attachment = new Attachment();
        attachment.setName("wj");
        YuelyLog yuelyLog = new YuelyLog();
        yuelyLog.setAttachment(attachment);
        yuelyLog.setDate(new Date().toString());
        yuelyLog.setName("dn");

        YuelyLog clone = yuelyLog.clone();
        clone.getAttachment().setName("clone");
        System.out.println("yelyLog:name="+(yuelyLog.getAttachment().getName()));
    }

测试效果
输出:clone
说明在修改浅拷贝队形的同时原对象也发生了变化,这是一种非常危险的事情,如果处理不当,对全局性的变量或者原对象进项操作会引起大bug

其实我们拷贝一个对象就是希望他是独立的,可操作的,不会因为修改他而引起原对象发生变化。

二、下面通过序列化实现深拷贝

public class YuelyLog implements Serializable,Cloneable {
    private Attachment attachment;
    private String name;
    private String date;

    @Override
    protected YuelyLog clone() throws CloneNotSupportedException {
        return (YuelyLog)super.clone();
    }

    public Attachment getAttachment() {
        return attachment;
    }

    public void setAttachment(Attachment attachment) {
        this.attachment = attachment;
    }

    public String getName() {
        return name;
    }

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

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    /**
     * 使用序列化技术实现深拷贝
     * @return
     */
    public YuelyLog deepClone() throws IOException,ClassNotFoundException{
        //将对象写入流中
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(this);
        //从流中取出
        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
        return (YuelyLog)objectInputStream.readObject();

    }
}

继续上面的测试会发现一切如我们所期望。

在这里强调一点,当然如果你能保证在拷贝对象后,你只是对拷贝对象成员变量为基本类型和String类型进行操作,可以使用浅拷贝,像对复杂对象操作,我们一般使用深拷贝,或者对非基本类型单独实现拷贝进行修改。业务中灵活掌握。
想了解更多java相关技术,请关注公众号“JavaEE那些事”

扫描下面二维码,更多技术资料等你来拿
这里写图片描述

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值