Java中的Cloneable接口是一個標記接口,用于標識一個類可以被克隆。該接口沒有定義任何方法,但是在使用clone()方法進行對象克隆時,需要實現Cloneable接口。
淺拷貝:
當一個對象被淺拷貝時,它的所有基本數據類型的成員變量都會被復制,而引用類型的成員變量只會復制引用地址,不會復制引用的對象本身。也就是說,原對象和克隆對象之間會共享引用類型的成員變量。
深拷貝:
當一個對象被深拷貝時,它的所有成員變量都會被復制,包括基本數據類型和引用類型。深拷貝會創建一個新的對象,新對象和原對象之間沒有任何關聯。
實現淺拷貝:
要實現淺拷貝,需要在需要克隆的類中實現Cloneable接口,并重寫clone()方法。在clone()方法中,調用super.clone()方法進行對象的拷貝。
public class MyClass implements Cloneable {
private int value;
private String name;
private List<String> list;
// 構造方法和其他方法
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
實現深拷貝:
要實現深拷貝,需要在需要克隆的類中實現Cloneable接口,并重寫clone()方法。在clone()方法中,除了調用super.clone()方法進行對象的拷貝外,還需要將引用類型的成員變量也進行克隆。
public class MyClass implements Cloneable {
private int value;
private String name;
private List<String> list;
// 構造方法和其他方法
@Override
public Object clone() throws CloneNotSupportedException {
MyClass cloned = (MyClass) super.clone();
cloned.list = new ArrayList<>(this.list);
return cloned;
}
}
需要注意的是,如果引用類型的成員變量是可變對象(例如List、Map等),需要對其進行深拷貝,否則原對象和克隆對象之間仍然會共享引用類型的成員變量。如果引用類型的成員變量是不可變對象(例如String),則可以直接復制引用地址,因為不可變對象無法修改。