[英]how Immutable class is created having mutable object as refernce
我問的問題是“如何在java中創建不可變對象”。
所以我有一個來自第三方的Address類,它不繼承任何Cloneable接口及其可變類。 看起來像這樣
public class Address {
private String city;
private String address;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
現在我有另一個名為Person的不可變類,它實現了Cloneable接口,並且還覆蓋了clone方法.Class看起來像這樣
public class Person implements Cloneable {
private String name;
private Address address;
public Person() {
}
public Person(String name, Address address) {
this.name = name;
this.address = address;
//this.address = (Address) address.clone();
}
public String getName() {
return name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person person = (Person) super.clone();
return super.clone();
}
public Address getAddress() {
return address;
}
@Override
public String toString() {
return "name:" + name + ", address" + address.getAddress() + ", city="
+ address.getCity();
}
}
現在我的問題是,我當然可以克隆Person類對象但是如何克隆類實例。 我還閱讀了一些關於淺層克隆和深度克隆的文章。 但我無法理解使用三十方API可以做多深的克隆。 如果我理解克隆的錯誤,請糾正我。
我認為你理解得很好: clone
是一種糟糕的機制,實際上有一個完整的錯誤列表(請查看Effective Java)。 與您的情況特別相關,您無法使用final
字段深度克隆對象。
而是選擇用於復制對象的自定義機制,例如復制構造函數或專用方法。
內存序列化 - 反序列化循環也有一個技巧,但我不會真的推薦它,除非你的列表中的性能和效率不高。
Cloneable工具的許多問題之一是在調用super.clone()
之后,在返回克隆值之前,可能存在需要返回狀態的字段和-fix-。 這可以防止你在你的類中使這些字段成為final
,並且與不可變類的原則不一致。 此外,該設施可能會在您的班級中引入安全漏洞,主要是因為它依賴於創建對象的語言機制。
一個好的經驗法則是, 如果您可以避免在類中實現Cloneable,那么請避免使用它。
正如Marko所提到的,復制工廠方法的復制構造者通常是優越的策略,不依賴於有缺陷的,用於創建對象的語言機制。 使用我所知道的clone()
方法的唯一好處是獲取不可變值數組(如基元或Strings
防御性副本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.