對象的深拷貝、淺拷貝

(一)
淺拷貝:是拷貝的一個引用;
比如說:對象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的過程:拷貝出來的新對象,先分配和源對象大小相同的內存,然後再使用源原對象中對應的各個域填充新對象的域,然後將這個新對象的引用發佈

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