簡體   English   中英

如何創建具有可變對象的不可變類作為引用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM