一、淺複製和深複製的區別
在Java中,對象的複製一般分為兩種:淺複製和深複製。淺複製是指只複製對象的基本類型值以及對其他對象的引用,並不複製其他對象本身;而深複製則是將對象自身和對象所引用的對象(如果有)均複製一份。淺複製和深複製的區別可以通過下面的代碼演示:
//定義Person類 public class Person implements Cloneable { private String name; private Integer age; private PhoneNumber phoneNumber; public Person(String name, Integer age, PhoneNumber phoneNumber) { this.name = name; this.age = age; this.phoneNumber = phoneNumber; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } //getters and setters } //定義PhoneNumber類 public class PhoneNumber { private String phoneNumber; public PhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } } //測試淺複製 Person person1 = new Person("Tom", 20, new PhoneNumber("123456")); Person person2 = (Person) person1.clone(); person2.getPhoneNumber().setPhoneNumber("654321"); System.out.println(person1.getPhoneNumber().getPhoneNumber()); //654321 //測試深複製 public class PhoneNumber implements Cloneable { private String phoneNumber; public PhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } //getters and setters } public class Person implements Cloneable { private String name; private Integer age; private PhoneNumber phoneNumber; public Person(String name, Integer age, PhoneNumber phoneNumber) { this.name = name; this.age = age; this.phoneNumber = phoneNumber; } @Override protected Object clone() throws CloneNotSupportedException { Person person = (Person) super.clone(); person.phoneNumber = (PhoneNumber) phoneNumber.clone(); //深複製 return person; } //getters and setters } Person person1 = new Person("Tom", 20, new PhoneNumber("123456")); Person person2 = (Person) person1.clone(); person2.getPhoneNumber().setPhoneNumber("654321"); System.out.println(person1.getPhoneNumber().getPhoneNumber()); //123456
二、實現Cloneable接口
在Java中,任何一個類如果要實現複製的功能,都需要實現Cloneable接口,並且重寫Object類的clone方法。
Cloneable接口只是一個標識接口,它沒有任何方法需要實現。它的作用是告訴JVM,這個類是可以被複制的。
public class Person implements Cloneable { private String name; private Integer age; private PhoneNumber phoneNumber; public Person(String name, Integer age, PhoneNumber phoneNumber) { this.name = name; this.age = age; this.phoneNumber = phoneNumber; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } //getters and setters }
三、深度複製實現方式
上面我們已經提到,如果要實現深度複製,可以在clone方法中將所有引用類型的屬性均進行一次clone操作,從而實現深度複製。但這種方式有一個缺陷,如果對象的引用鏈比較長,這種方式會顯得非常繁瑣和複雜。
可以通過序列化和反序列化的方式來實現深度複製。只需要將對象序列化成二進制流,再將二進制流反序列化成新的對象,就可以實現深度複製。代碼如下:
public static Object deepClone(Object object) throws IOException, ClassNotFoundException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(object); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); return ois.readObject(); } //測試深度複製 Person person1 = new Person("Tom", 20, new PhoneNumber("123456")); Person person2 = (Person) deepClone(person1); person2.getPhoneNumber().setPhoneNumber("654321"); System.out.println(person1.getPhoneNumber().getPhoneNumber()); //123456
四、總結
Java中的對象複製一般分為淺複製和深複製。淺複製只複製對象的基本類型值以及對其他對象的引用,並不複製其他對象本身;深複製則是將對象自身和對象所引用的對象(如果有)均複製一份。
另外,如果要實現複製的功能,需要實現Cloneable接口,並且重寫Object類的clone方法。如果要實現深度複製,可以在clone方法中將所有引用類型的屬性均進行一次clone操作,也可以通過序列化和反序列化的方式來實現深度複製。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/154825.html