java Clone接口和深拷貝詳解

對於數組的拷貝,如果是簡單類型的話是深拷貝,如果是引用類型的話是淺拷貝,但是因為java是面向對象的,在回答面試官問題的時候,我們可以不用說的這麼細,可以直接說淺拷貝。

代碼示例1

class Person implements Cloneable{//如果想克隆自定義類,那麼需要在自定義類上實現Cloneable接口
    public int age;
    /*疑問:為什麼這個接口是空接口呢?這是一個面試問題。
    空節課:也把它叫做標記接口。其實就是這個意思:隻要一個類實現瞭這個接口,那麼就標記這個類是可以進行clone的
    *
    * 2:重寫clone方法*/
    @Override
    protected Object clone() throws CloneNotSupportedException {//重寫瞭父類的克隆方法
        return super.clone();
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
        System.out.println(person1.age);
        System.out.println(person2.age);
        System.out.println("=======修改=======");
        person2.age = 99;
        System.out.println(person1.age);
        System.out.println(person2.age);
    }
    /*public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6};
        int[] array2 = array.clone();//對這個數組進行克隆
        array2[0] = 33;//改變拷貝後的數組元素的值不會影響原來數組的元素,這種情況是深拷貝
        System.out.println(Arrays.toString(array2));
        System.out.println(Arrays.toString(array));
    }*/
}

輸出為:

在這裡插入圖片描述

因為改變的是簡單類型,所以這種情況是深拷貝。

代碼示例2

class Money{
    double money = 12.5;
}
class Person implements Cloneable{//如果想克隆自定義類,那麼需要在自定義類上實現Cloneable接口
    public int age;
    /*疑問:為什麼這個接口是空接口呢?這是一個面試問題。
    空節課:也把它叫做標記接口。其實就是這個意思:隻要一個類實現瞭這個接口,那麼就標記這個類是可以進行clone的
    *
    * 2:重寫clone方法*/
    Money m = new Money();
    @Override
    protected Object clone() throws CloneNotSupportedException {//重寫瞭父類的克隆方法
        return super.clone();
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("=========修改==========");
        person2.m.money = 99.9;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

輸出為:

在這裡插入圖片描述

可以參考以下圖分析:

在這裡插入圖片描述

這種情況就是淺拷貝,那麼可以將這個淺拷貝變成深拷貝嗎?隻需要將Money也克隆一下

class Money implements Cloneable{//如果想要變成深拷貝的話,那麼money也需要被克隆。
    double money = 12.5;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{//如果想克隆自定義類,那麼需要在自定義類上實現Cloneable接口
    public int age;
    Money m = new Money();
    @Override
    protected Object clone() throws CloneNotSupportedException {//重寫瞭父類的克隆方法
        Person p = (Person)super.clone();//1:將當前的對象克隆一份,克隆person
        p.m = (Money) this.m.clone();//2:克隆當前的Money對象
        return p;
    }
}
public class TestDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("=========修改==========");
        person2.m.money = 99.9;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

在這裡插入圖片描述

這樣就就將淺拷貝轉變成瞭深拷貝,可以參考以下圖分析:

在這裡插入圖片描述

總結

本篇文章就到這裡瞭,希望能給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: