深拷贝和浅拷贝

深拷贝和浅拷贝

1.类型

拷贝一般分为二大类 引用拷贝对象拷贝,我们通常讲的深拷贝浅拷贝都属于对象拷贝

2.引用拷贝

定义:顾名思义,即是对引用地址的拷贝,说明引用地址一样,指向堆中的对象是同一个对象。
如果对一个对象进行改变,其他对象也会跟着改变。

Teacher teacher = new Teacher("Taylor",26);
// 这一步结束后otherteacher的地址和teacher的地址相同
Teacher otherteacher = teacher;
System.out.println(teacher);
System.out.println(otherteacher);

/**
* @output 
* blog.Teacher@355da254
* blog.Teacher@355da254
*
/*
结果分析:由输出结果可以看出,它们的地址值是相同的,那么它们肯定是同一个对象。teacher和otherteacher的只是引用而已,他们都指向了一个相同的对象Teacher(“Taylor”,26)。这就叫做引用拷贝。

image-20230317141922795

3.对象拷贝

定义:对象拷贝指 对某一对象进行拷贝,是创建了一个全新的对象,也就是内存中存在二个不同地址的对象,这二个对象的基本数据类型变量的内容值都是一样的,但所包含的对象变量的地址可能一样可能不一样,浅拷贝与深拷贝的区别就在这里

public static class Person implements Cloneable{
        public String name;
        public int age;
    	/** Person类中不仅仅有像name,age这样的基本数据类型也存在着house这样的对象变量
    		浅拷贝是只拷贝Person中的基本数据类型,而不拷贝对象
            深拷贝是将所有类型的数据都拷贝
            通俗的来说深拷贝比浅拷贝拷贝的更加彻底
    	*/
        public House house; 

        public Person(String name, int age, House house) {
            this.name = name;
            this.age = age;
            this.house = house;
        }
        
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
}

注意:clone的使用需要先在Teacher类中实现Cloneable接口,然后重写之中的clone方法

image-20230317143507914

4.浅拷贝

定义:当前对象里包含有对象变量,如果复制的对象中的对象变量和原对象里的对象地址值是相同的,即引用拷贝,则称之为浅拷贝。我们也可以称之为部分拷贝,即拷贝的不彻底。

public static void main(String[] args) {
        Person person1=new Person("A",20, new House("aa"));
        try {
            Person person2= (Person) person1.clone();

            System.out.println("persion1 = " + person1+" house = "+person1.house);
            System.out.println("persion2 = " + person2+" house = "+person2.house);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

/**
  * output: 
  * persion1 = Person@402a079c house = House@59ec2012
  * persion2 = Person@4cf777e8 house = House@59ec2012
*/

可以看到我们对Person1进行了clone,person2的内存地址和person1的不一样,说明这是一个新对象,然而在看对象House,内存地址是一样的,说明对于成员变量只进行了内存引用。这个就是浅拷贝。
总结:虽然对象进行了拷贝,但内部变量没有完全进行拷贝。这就是浅拷贝,即拷贝的不彻底

5.深拷贝

当前对象里包含有对象变量,如果复制的对象中的对象变量和原对象里的对象地址值是不同的,即创建了一个新的对象,则称之为深拷贝。我们也可以称之为完全拷贝,内部进行了彻底拷贝。

现在我们对 clone方法做一些修改

public class Person implements Cloneable {
        public String name;
        public int age;
        public House house;

        public Person(String name, int age, House house) {
            this.name = name;
            this.age = age;
            this.house = house;
        }

        @Override
        public Object clone() throws CloneNotSupportedException {
            Person person = (Person) super.clone();
            //在原有的基础上 clone了成员变量对象
            person.house = (House) person.house.clone();
            return person;
        }
    }

class House implements Cloneable {
        public String address;

        public House(String address) {
            this.address = address;
        }
        //实现clone方法
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }

/**
  * output: 
  * persion1 =Person@402a079c house = House@59ec2012
  * persion2 = Person@4cf777e8 house = House@2f686d1f
*/
可以看到不仅Person对象内存地址不一样,House的内存地址也不一样了,这说明Person1和Person2的内容,成员变量也完全不相同了。

总结:一个对象进行了clone,不仅仅自身clone了一个新的,其内部的成员变量也都clone了一个新的,这就是深拷贝。

所以,如果一个对象中仅包含基本数据类型,则浅拷贝和深拷贝则没区别。如果一个对象中包含了对象变量,则对这些对象变量的拷贝 就成了 浅拷贝和深拷贝的区别。
posted @   zhangyf1121  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示