一、淺複製和深複製的區別
在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
微信掃一掃
支付寶掃一掃