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