淺複制和深複制的概念
複制在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類型好像複制的并不是引用而是字元串的值,這就讓我很納悶了,索性暫時當做是特殊的類型來處理了。如果有哪位小夥伴可以告知的話,希望可以留言。