Java 中對象的拷貝實際上分為深拷貝和淺拷貝兩種方式。深拷貝是將對象完全復(fù)制一份,新對象的所有屬性都和原對象一樣,而淺拷貝只是把原對象的引用復(fù)制給新的對象,新對象和原對象的屬性指向的依然是同一個對象。
Java 提供了兩種方式來實現(xiàn)對象的拷貝。第一種方式是通過實現(xiàn) Cloneable 接口和重寫 clone() 方法實現(xiàn),第二種方式是通過序列化和反序列化實現(xiàn)。其中,Cloneable 接口和 clone() 方法是 Java 內(nèi)置的,在使用過程中需要注意幾個問題。
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 接口實現(xiàn)深拷貝的示例代碼,需要注意的是:
- 必須實現(xiàn) Cloneable 接口,否則會拋出 CloneNotSupportedException 異常。
- 如果對象屬性中還包含了其他對象,則需要對其他對象進行深拷貝。
- Cloneable 接口沒有任何方法,它只是一個標(biāo)記接口。
下面是通過序列化和反序列化實現(xiàn)深拷貝的示例代碼:
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(); } }
以上是通過序列化和反序列化實現(xiàn)深拷貝的示例程序,需要注意的是:
- 對象必須實現(xiàn) Serializable 接口。
- 通過序列化和反序列化方式可以遞歸地實現(xiàn)深拷貝。
- 需要捕獲 IOException 和 ClassNotFoundException 異常。
無論是通過 Cloneable 接口實現(xiàn)深拷貝還是通過序列化和反序列化方式實現(xiàn)深拷貝都需要注意對象屬性的深淺拷貝問題。