对象的深拷贝、浅拷贝

(一)
浅拷贝:是拷贝的一个引用;
比如说:对象A,对A进行浅拷贝之后,拷贝出来一个对象B,则B与A会指向同一个引用,如图所示:

在这里插入图片描述

class Person {


    private  String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
public class TestClone {


    public static void main(String[] args) {

        Person   person1=new Person("张三",12);
        Person person2=person1;
        System.out.println(person1);
        System.out.println(person2);

      
    }

}

如图所示:是浅拷贝
其结果为:
在这里插入图片描述

根据结果可以看出,person1与person2的地址相同,说明person1与person2指向堆上的同一个对象,这就是浅拷贝
(二)
深拷贝:是重新创建了一个新对象,而不是拷贝的一个引用;
比如:对象A,对A进行深拷贝之后,会重新创建一个对象,B会指向这个新创建的对象,如图所示:
在这里插入图片描述

如果想要深拷贝一个对象,这个类必须实现Cloneable接口实现clone方法

class Person implements  Cloneable{


    private  String name;
    private int age;

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

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


    public static void main(String[] args) {

        Person   person1=new Person("张三",12);
        System.out.println(person1);
        try {
            Person person3= (Person) person1.clone();

            System.out.println(person3);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

}

其结果为:
在这里插入图片描述

从图可以看出:
person1和person3的地址不一样,说明,person1和person3没有指向堆上的同一个对象;这就是深拷贝;

(三)

如果对象中包含的域引用了可变的对象,那么在拷贝该对象时,要想让这个拷贝的对象和源对象完全彼此独立,那么在引用链上的每一级对象都要被显示的拷贝;

class Person implements  Cloneable{


    public   Object[] array; //包含了一个引用类型
    public int age;

    public Person(int age) {
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {

        return super.clone();//未对引用链上的每一级对象都进行显示的拷贝
      
       
    }
}
public class TestClone {


    public static void main(String[] args) {

        Person   person1=new Person(12);
        person1.array= new Object[] {1, 2};
        System.out.println(person1);
        System.out.println(person1.array);

        try {
            Person person3= (Person) person1.clone();

            System.out.println(person3);

            System.out.println(person3.array);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

}

结果为:
在这里插入图片描述

发现深拷贝之后,对象内部的对象是指向同一个地址的;

下面代码中:是对引用链上的每一级对象都进行显示的拷贝:

class Person implements  Cloneable{


    public   Object[] array;
    public int age;

    public Person(int age) {
        this.age = age;
    }

    @Override
    protected Person clone() throws CloneNotSupportedException {

        Person result= (Person) super.clone();
        result.array=array.clone();//引用链上的每一级对象都被显示的拷贝
        return result;
    }
}
public class TestClone {


    public static void main(String[] args) {

        Person   person1=new Person(12);
        person1.array= new Object[] {1, 2};
        System.out.println(person1);
        System.out.println(person1.array);

        try {
            Person person3= (Person) person1.clone();

            System.out.println(person3);

            System.out.println(person3.array);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

}

结果为:
在这里插入图片描述

发现,当对该对象上的引用链上的每一级对象都进行显示的拷贝后,其内部包含的对象指向不一样的地址,拷贝的对象与源对象完全独立;

整体来说:clone的过程:拷贝出来的新对象,先分配和源对象大小相同的内存,然后再使用源原对象中对应的各个域填充新对象的域,然后将这个新对象的引用发布

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章