彻底搞懂深拷贝和浅拷贝

本文详细介绍了Java中浅拷贝和深拷贝的概念,通过实例展示了如何处理引用数据类型的拷贝问题。在浅拷贝中,基本数据类型不受影响,而引用数据类型会共享同一内存空间。深拷贝则为引用数据类型创建新的内存副本,确保新旧对象的独立性。文章提供了一组完整的代码示例来演示这两种拷贝方式的区别。
摘要由CSDN通过智能技术生成

深拷贝和浅拷贝只对引用数据类型而言的!,基本数据类型不存在深浅拷贝
本文的所有代码放在文章的后面

浅拷贝

  • 如果被拷贝对象的成员变量为基本数据类型,那么浅拷贝将会进行值传递,赋值给新对象的成员变量,两者互不关联。
  • 如果被拷贝对象的成员变量是引用数据类型,那么浅拷贝只会将该变量的地址赋值给新对象的成员变量,它们指向同一空间

深拷贝

  • 如果被拷贝对象的成员变量为引用数据类型时,深拷贝将会为新对象的成员变量开辟新的内存空间,新旧对象的成员变量指向不同的内存空间

上代码测试

  1. 浅拷贝:成员变量为基本数据类型

Father类需要实现Cloneable接口,并使用其默认实现

@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone(); //To change body of generated methods, choose Tools | Templates.
}

将旧对象的基本数据类型的变量的值直接传递给新对象的成员变量

Father father1 = new Father("wwj",23);
Father father2 = (Father) father1.clone();
father2.setAge(39);
System.out.println(father1);
System.out.println(father2);

运行结果
在这里插入图片描述
分析:可知,father1的两个属性都是基本数据类型,修改了father2的属性,father1的属性没变化,两者互不影响

  1. 浅拷贝:成员变量为引用数据类型

Husband类实现Cloneable接口,并使用其提供的默认实现

@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone(); //To change body of generated methods, choose Tools | Templates.
}

将旧对象的成员变量的地址赋值给新对象的成员变量,两者指向同一个内存空间

 Husband husband1 = new Husband("wwj", 23);
 Husband husband2 = (Husband) husband1.clone();
 //这里的wife是husband的一个引用属性
 husband2.wife.name = "hhhh";
 System.out.println(husband1);
 System.out.println(husband2);

在这里插入图片描述
分析可知:修改了新对象的wife引用属性,就对象的wife属性也同样发生变化

  1. 深拷贝–仅针对成员变量为引用数据类型

需要Husband类重写实现Cloneable接口,重写并修改clone()方法

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;
        deep = super.clone();//完成对基本数据类型变量的拷贝
        Husband husband = (Husband)deep;//转换类型
        husband.wife = (WIfe) wife.clone();//完成对引用类型的成员变量的拷贝
        return husband; //To change body of generated methods, choose Tools | Templates.
    }

新对象为引用类型的成员变量开辟新的内存空间,新旧对象的成员变量指向不同的内存空间,互不影响

 Husband husband1 = new Husband("wwj", 23);
 Husband husband2 = (Husband) husband1.clone();
 husband2.wife.name = "hhhh";
 System.out.println(husband1);
 System.out.println(husband2);

在这里插入图片描述
分析可知:我们重写了clone()方法,完成了对引用类型的成员变量的拷贝(开辟新空间),新旧对象的操作互不影响
原创不易,可以给我赞咩!_(:з」∠)_嘻嘻

CopyTest


package test;

public class CopyTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        
        //浅拷贝:成员变量为基本数据类型-->值传递
//        Father father1 = new Father("wwj",23);
//        Father father2 = (Father) father1.clone();
//        father2.setAge(39);
//        System.out.println(father1);
//        System.out.println(father2);
        
        //浅拷贝:成员变量为引用数据类型-->不重写修改clone方法那么指向同一个空间,修改其中一个引用变量另外一个也会发生改变
//        Husband husband1 = new Husband("wwj", 23);
//        Husband husband2 = (Husband) husband1.clone();
//        husband2.wife.name = "hhhh";
//        System.out.println(husband1);
//        System.out.println(husband2);
        
        
        //深拷贝--成员变量为引用数据类型,开辟新的内存空间完成拷贝
        Husband husband1 = new Husband("wwj", 23);
        Husband husband2 = (Husband) husband1.clone();
        husband2.wife.name = "hhhh";
        System.out.println(husband1);
        System.out.println(husband2);
    }
}

Father

package test;

import java.util.Objects;

public class Father implements Cloneable{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Father(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Father{" + "name=" + name + ", age=" + age + '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); //To change body of generated methods, choose Tools | Templates.
    }
    
}

Husband

package test;

import java.util.Objects;

public class Husband implements Cloneable{
    WIfe wife = new WIfe("lzz");
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Husband(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Husband{" + "wife=" + wife + ", name=" + name + ", age=" + age + '}';
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;
        deep = super.clone();//完成对基本数据类型变量的拷贝
        Husband husband = (Husband)deep;//转换类型
        husband.wife = (WIfe) wife.clone();//完成对引用类型的成员变量的拷贝
        return husband; //To change body of generated methods, choose Tools | Templates.
    }
}

Wife

package test;

public class WIfe implements Cloneable{

    String name;
    
    public WIfe(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "WIfe{" + "name=" + name + '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); //To change body of generated methods, choose Tools | Templates.
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值