天天看點

談談淺複制和深複制的想法淺複制和深複制的概念手寫淺複制和深複制Java提供的接口

淺複制和深複制的概念

複制在Java中一般是複制一個已經存在的對象,我們都知道Java中有基本資料類型和引用資料類型,也正是因為這樣,才會有淺複制和深複制的說法。

淺複制:如果是基本資料類型的話,會将值複制一份,如果是引用類型的話,會将引用變量複制一份,但是指向的還是同一個執行個體對象。

深複制:針對引用資料類型而來,意味複制的是執行個體對象的内容,而不是複制引用變量。

談談淺複制和深複制的想法淺複制和深複制的概念手寫淺複制和深複制Java提供的接口

從圖中可以看出,引用資料類型也被拷貝了一份,這樣就可以單獨進行修改而不影響原來的值。

下面就用兩種方式來寫淺複制和深複制:手寫+Java提供的接口

手寫淺複制和深複制

public class Color {
    private String colorName;
    public Color(String colorName) {
        this.colorName = colorName;
    }
    public String getColorName() {
        return colorName;
    }

}
           
public class Car implements Cloneable {
    private String name;
    private float price;
    private Color color;
    public Car(String name, float price, Color color) {
        this.name = name;
        this.price = price;
        this.color = color;
    }
    public Car copy() {
        // 重寫new一個color,放到要複制的car對象中
        Color color = new Color(this.color.getColorName());
        // 重新new出一個Car對象并傳回,這就是複制的一個獨立的對象
        Car car = new Car(this.name, this.price, color);
        return car;
    }
}
           

Java提供的接口

Java提供了一個Cloneable接口,用來标志該類可以被克隆,如果實作了這個接口,那麼就需要重寫clone方法,在這個方法裡面進行深複制的過程。

public class Color implements Cloneable {
    private String colorName;

    public Color(String colorName) {
        this.colorName = colorName;
    }

    public String getColorName() {
        return colorName;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
           
public class Car implements Cloneable {
    private String name;
    private float price;
    private Color color;

    public Car(String name, float price, Color color) {
        this.name = name;
        this.price = price;
        this.color = color;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 此時的car對象中的color和this的car對象中的color指向的是同一個color對象
        Car car = (Car) super.clone();
        // 進一步拷貝複制
        car.color = (Color) this.color.clone();
        return car;
    }
}
           

上面兩中方式都很好測試,作者在實驗的時候有個疑問:String類型是引用類型的,但是在淺複制的時候,String類型好像複制的并不是引用而是字元串的值,這就讓我很納悶了,索性暫時當做是特殊的類型來處理了。如果有哪位小夥伴可以告知的話,希望可以留言。

繼續閱讀