繁体   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