Java 中對象的拷貝實際上分為深拷貝和淺拷貝兩種方式。深拷貝是將對象完全復制一份,新對象的所有屬性都和原對象一樣,而淺拷貝只是把原對象的引用復制給新的對象,新對象和原對象的屬性指向的依然是同一個對象。
Java 提供了兩種方式來實現對象的拷貝。第一種方式是通過實現 Cloneable 接口和重寫 clone() 方法實現,第二種方式是通過序列化和反序列化實現。其中,Cloneable 接口和 clone() 方法是 Java 內置的,在使用過程中需要注意幾個問題。
public class Person implements Cloneable { private String name; private int age; private Listhobbies; public Person(String name, int age, List hobbies) { this.name = name; this.age = age; this.hobbies = hobbies; } @Override protected Object clone() throws CloneNotSupportedException { Person person = (Person)super.clone(); person.hobbies = (List )((ArrayList)hobbies).clone(); return person; } }
以上是通過 Cloneable 接口實現深拷貝的示例代碼,需要注意的是:
- 必須實現 Cloneable 接口,否則會拋出 CloneNotSupportedException 異常。
- 如果對象屬性中還包含了其他對象,則需要對其他對象進行深拷貝。
- Cloneable 接口沒有任何方法,它只是一個標記接口。
下面是通過序列化和反序列化實現深拷貝的示例代碼:
public class Person implements Serializable { private String name; private int age; private Listhobbies; public Person(String name, int age, List hobbies) { this.name = name; this.age = age; this.hobbies = hobbies; } public Person deepClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(this); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); return (Person)ois.readObject(); } }
以上是通過序列化和反序列化實現深拷貝的示例程序,需要注意的是:
- 對象必須實現 Serializable 接口。
- 通過序列化和反序列化方式可以遞歸地實現深拷貝。
- 需要捕獲 IOException 和 ClassNotFoundException 異常。
無論是通過 Cloneable 接口實現深拷貝還是通過序列化和反序列化方式實現深拷貝都需要注意對象屬性的深淺拷貝問題。