Java对象的深复制和浅复制详解

前言:

本文以实例介绍Java对象的深复制和浅复制使用对比。

浅复制:被复制的对象的所有变量都含有原来对象的相同值,对象中对其他对象的引用,仍指向原对象。
深复制:将引用对象的变量指向新对象,而不是原对象。

浅复制所复制的是对象的引用,对象的数据结构和数据都被复制,修改原对象也会对浅复制的对象也会发生同样的改变。如:Object a = b;即为浅复制。

深复制(克隆)所复制对象的数据结构,跟原对象不再有关联,修改原对象也不会对深复制对象产生影响。
如:Object a = b.clone();通过克隆深复制。

一.深复制的实现步骤

  1. 对象实现Cloneable接口(或Serializable接口)。
  2. 对象重写clone()方法。
  3. 调用object.clone()方法得到克隆对象。

实例

package com.deepcopy.demo;

//实现Cloneable接口
public class User implements Cloneable {
    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    //重写clone()方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        User user = null;
        user = (User) super.clone();
        return user;
    }
}

上述是一个标准的JavaBean对象,在此基础上实现了Cloneable接口,重写clone()方法,在此方法中将父类的克隆对象强制转换为User类即可。

注:强制转换最好加上try-catch捕获异常,为简洁展示,故此省略。
注:String 类型是拥有值类型特征的引用类型

二.深复制和浅复制的对比:

package com.deepcopy.demo;

public class DeepCopy {
    private User user;//原对象
    private User userClone;// 克隆对象
    private User userCopy;// 浅复制对象

    public static void main(String[] args) {
        DeepCopy dCopy = new DeepCopy();
        dCopy.test();
    }

    private void test() {
        //实例化一个普通对象
        user = new User();
        user.setId("001");
        user.setName("张三");
        System.out.println("原对象user:" + user.getId()+","+user.getName());
        //浅复制user对象
        userCopy = user;

        //克隆一份刚才的对象
        try {
            userClone = (User) user.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        //改变原对象user的属性,观察浅复制对象和克隆对象的变化
        user.setId("002");
        user.setName("李四");

        System.out.println("改变后的原对象user:" + user.getId()+","+user.getName());
        System.out.println("浅复制对象userCopy:" + userCopy.getId()+","+userCopy.getName());
        System.out.println("克隆对象userClone:" + userClone.getId()+","+userClone.getName());
    }
}

输出结果:

原对象user:001,张三
改变后的原对象user:002,李四
浅复制对象userCopy:002,李四
克隆对象userClone:001,张三

从输出结果中可以看出,当原对象修改后,浅复制的对象也同样变化,但克隆对象(深复制)没有发生变化。

三.对象中包含其他JavaBean对象的克隆方法:

如果User中还包含其他的JavaBean对象时,仅通过上述的方法克隆后,该JavaBean对象不会被深复制。即修User对象内部的JavaBean对象的属性,克隆对象中的JavaBean对象也会发生变化,对对象中的对象是浅复制。

正确的做法:应该让内部JavaBean也实现ICloneable接口,并且重写clone()方法。然后在对其修改操作时,就不会影响克隆对象中的JavaBean对象了。若果第二层JavaBean对象中,还包含第三层,克隆方法同上,以此类推。

四.总结:

浅复制对象只是将复制原对象的引用地址,而克隆对象才会复制对象本身(数据结构),并与原对象断开关系。理解了对象的深复制,才能更好的理解设计模式的原型模式(点击查看)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值