浅拷贝 和 深拷贝

本文深入探讨Java中对象的深拷贝与浅拷贝概念,通过实例代码演示了如何实现对象的深拷贝,特别是在包含引用类型成员变量的情况下。文章详细解释了深拷贝与浅拷贝的区别,以及实现深拷贝时需要注意的问题。

Father

package com.kevin.test.test;

/**
 * Created by jinyugai on 2018/11/16.
 */
public class Father implements Cloneable {
    public String xm;
    public Child child;
    public Girl girl;
    public Father(Child child,Girl girl) {
        this.child = child;
        this.girl = girl;
    }


    @Override
    protected Object clone() throws CloneNotSupportedException {
        Father father = (Father)super.clone();
        father.girl = (Girl)girl.clone();
        return father;
    }
}

 

Child 

package com.kevin.test.test;

/**
 * Created by jinyugai on 2018/11/16.
 */
public final class Child {
    public String name;
}

Girl 

package com.kevin.test.test;

/**
 * Created by jinyugai on 2018/11/16.
 */
public class Girl implements Cloneable {
    public String name;


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

 

 测试

 

package com.kevin.test.test;

/**
 * Created by jinyugai on 2018/11/16.
 */
public class CloneTest {
    public static void main(String[] args) {
        Father father1 = new Father(new Child(),new Girl());
        father1.xm = "Kevin";
        father1.child.name = "youyou";
        father1.girl.name = "toto";
        try {
            //浅拷贝
            // child类虽然声明为final修饰,但是child并没有被重新new 没有重新划分内存
            //深拷貝
            // girl类深拷贝
            Father father2 = (Father)father1.clone();
            father2.xm = "kevin2";
            father2.child.name = "youyou2";
            father1.girl.name = "toto2";
            System.out.println("打印fathe ===========");
            System.out.println("打印fathe1 :"+father1.xm);
            System.out.println("打印fathe2 :" + father2.xm);
            System.out.println("打印child.name ===========");
            System.out.println("打印fathe1 child.name:"+father1.child.name);
            System.out.println("打印fathe2 child.name:"+father2.child.name);
            System.out.println("打印girl.name ===========");
            System.out.println("打印fathe1 girl.name:"+father1.girl.name);
            System.out.println("打印fathe2 girl.name:"+father2.girl.name);
            System.out.println("对比是否指向同一个引用 ===========");
            System.out.println(father1.xm == father2.xm);
            System.out.println(father1.child == father2.child);
            System.out.println(father1.girl == father2.girl);



        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }
}

 结果--浅拷贝--直接复制的是属性对象的地址 ,没有new一个新的

打印fathe ===========
打印fathe1 :Kevin
打印fathe2 :kevin2
打印child.name ===========
打印fathe1 child.name:youyou2
打印fathe2 child.name:youyou2
打印girl.name ===========
打印fathe1 girl.name:toto2
打印fathe2 girl.name:toto
对比是否指向同一个引用 ===========
false
true
false

 深拷贝--如果想要深拷贝一个对象, 这个对象必须要实现Cloneable接口,实现clone方法,并且在clone方法内部,把该对象引用的其他对象也要clone一份 , 这就要求这个被引用的对象必须也要实现Cloneable接口并且实现clone方法。

### 概念 - **浅拷贝**:浅拷贝只复制对象的一层属性,如果对象的属性是引用类型,浅拷贝只会复制引用,而不会复制引用指向的实际对象。也就是说,浅拷贝后的对象原对象共享部分数据。 - **深拷贝**:深拷贝会递归地复制对象的所有属性,包括引用类型的属性。深拷贝会创建一个完全独立的对象,新对象原对象在内存中是完全分离的,修改新对象不会影响原对象,反之亦然[^1]。 ### 区别 - **数据独立性**:浅拷贝后的对象原对象共享部分数据,修改其中一个对象的引用类型属性可能会影响到另一个对象;而深拷贝创建的是完全独立的对象,修改新对象不会对原对象产生影响[^1]。 - **性能开销**:浅拷贝只复制对象的一层属性,因此性能较高,执行效率快;深拷贝需要递归地复制对象的所有属性,性能相对较低,会占用更多的内存 CPU 资源[^2]。 ### 应用场景 - **浅拷贝的应用场景**:当数据结构简单,不需要完全独立的副本,且希望提高复制效率时,浅拷贝更合适。例如,在一些简单的复制操作中,只需要复制对象的一层属性,而不需要复制其引用的对象,使用浅拷贝可以节省性能开销[^3][^4]。 以下是 Python 中浅拷贝的示例代码: ```python import copy original_list = [1, [2, 3]] shallow_copied_list = copy.copy(original_list) # 修改浅拷贝列表中的可变元素 shallow_copied_list[1][0] = 99 print(original_list) # 输出: [1, [99, 3]] print(shallow_copied_list) # 输出: [1, [99, 3]] ``` - **深拷贝的应用场景**:当需要完全独立的数据副本,且不希望新对象原对象相互影响时,优先使用深拷贝。例如,在处理复杂的嵌套结构时,为了避免因共享引用导致的意外错误,使用深拷贝可以保证数据的正确性独立性[^3][^4]。 以下是 Python 中深拷贝的示例代码: ```python import copy original_list = [1, [2, 3]] deep_copied_list = copy.deepcopy(original_list) # 修改深拷贝列表中的可变元素 deep_copied_list[1][0] = 99 print(original_list) # 输出: [1, [2, 3]] print(deep_copied_list) # 输出: [1, [99, 3]] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值