在 Java 中,對象拷貝是一個常見需求。Java 中的拷貝有兩種方式:淺拷貝和深拷貝。不同的拷貝方式對于對象的數據成員的拷貝方式不同。
淺拷貝:將一個對象復制一份,新對象的引用指向原對象的內容。即:新對象的數據成員與原對象的數據成員共用同一個內存空間。
public class Person implements Cloneable { public String name; public int age; public Listhobbies; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class Main { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person(); person1.name = "Tom"; person1.age = 20; person1.hobbies = new ArrayList<>(); person1.hobbies.add("Swimming"); Person person2 = (Person) person1.clone(); System.out.println(person2.name); System.out.println(person2.age); System.out.println(person2.hobbies); person1.hobbies.add("Singing"); System.out.println(person2.hobbies); } }
上面的例子中,定義了一個 Person 類,包含了名字、年齡和愛好 3 個數據成員。在主函數中,先創建了一個 person1 對象,并設置了其數據成員的值。接著,通過調用 clone() 方法拷貝出了另一個 person2 對象。最后,對 person1 對象的 hobbies 列表添加了一個元素,輸出 person2 對象的 hobbies 列表,發現兩者的列表完全相同,即 hobbies 列表是同一個對象,指向同一個內存地址。
深拷貝:將一個對象復制一份,新對象的引用指向一個新的內存地址。即:新對象與原對象擁有完全獨立的內存空間。
public class Person implements Cloneable { public String name; public int age; public Listhobbies; @Override protected Object clone() throws CloneNotSupportedException { Person person = (Person) super.clone(); person.hobbies = new ArrayList<>(hobbies); return person; } } public class Main { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person(); person1.name = "Tom"; person1.age = 20; person1.hobbies = new ArrayList<>(); person1.hobbies.add("Swimming"); Person person2 = (Person) person1.clone(); System.out.println(person2.name); System.out.println(person2.age); System.out.println(person2.hobbies); person1.hobbies.add("Singing"); System.out.println(person2.hobbies); } }
在上面的代碼中,定義了 Person 類,并實現了 Cloneable 接口。在 clone() 方法中,先調用 super.clone() 方法得到一個克隆的對象,并為 hobbies 成員新創建一個 ArrayList 實例。這樣,新創建的對象和原對象就各自擁有了獨立的 hobbies 列表對象。在主函數中,輸出 person2 的 hobbies 列表,發現與 person1 的 hobbies 列表不同。