java如何實現對象的深克隆?
/**定義用戶**/
public class User {
private String name;
private Address address;
// constructors, getters and setters
}
/**地址**/
public class Address {
private String city;
private String country;
// constructors, getters and setters
}
重載clone()方法
Object父類有個clone()的拷貝方法,不過它是protected類型的,
我們需要重寫它并修改為public類型。
除此之外,子類還需要實現Cloneable接口來告訴JVM這個類是可以拷貝的。
重寫代碼
讓我們修改一下User類,Address類,實現Cloneable接口,使其支持深拷貝。
/**
* 地址
*/
public class Address implements Cloneable {
private String city;
private String country;
// constructors, getters and setters
@Override
public Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
}
/**
* 用戶
*/
public class User implements Cloneable {
private String name;
private Address address;
// constructors, getters and setters
@Override
public User clone() throws CloneNotSupportedException {
User user = (User) super.clone();
user.setAddress(this.address.clone());
return user;
}
}
需要注意的是,super.clone()其實是淺拷貝,
所以在重寫User類的clone()方法時,address對象需要調用address.clone()重新賦值。
擴展:
為什么要克隆?
大家先思考一個問題,為什么需要克隆對象?直接new一個對象不行嗎?
答案是:克隆的對象可能包含一些已經修改過的屬性,而new出來的對象的屬性都還是初始化時候的值,所以當需要一個新的對象來保存當前對象的“狀態”就靠clone方法了。那么我把這個對象的臨時屬性一個一個的賦值給我新new的對象不也行嘛?可以是可以,但是一來麻煩不說,二來,大家通過上面的源碼都發現了clone是一個native方法,就是快啊,在底層實現的。
提個醒,我們常見的Object a=new Object();Object b;b=a;這種形式的代碼復制的是引用,即對象在內存中的地址,a和b對象仍然指向了同一個對象。
而通過clone方法賦值的對象跟原來的對象時同時獨立存在的。