如何制作对象的防御性副本?

时间:2010-06-02 03:24:09

标签: java defensive-copy effective-java

如何制作包含不可变对象中可变字段的可变对象的防御性副本?

class ImmutableObject {

  private final MutableObject immutable_field;

  ImmutableObject(MutableObject y) {
    this.immutable_field = y;
  }
}

class MutableObject {

  public int mutable_field;
}
  • MutableObject没有允许我设置字段的构造函数。
  • MutableObject的当前状态应该在Immutable Object中捕获并且永远不会改变。

2 个答案:

答案 0 :(得分:7)

您需要做的是

  MutableObject return_immutable_field() {
    return immutable_field;
  }

更改为:

  MutableObject return_immutable_field() {
    MutableObject tmp = new MutableObject();
    tmp.mutable_field = immutable_field.mutable_field;
    return tmp;
  }

有关说明,请参阅http://www.javapractices.com/topic/TopicAction.do?Id=15

答案 1 :(得分:4)

好吧,假设对可变对象类的声明没有什么可做的,可以利用反射(ClassnewIntance()ClassgetFields() )创建新对象并复制字段值。您也可以这种方式实现深度复制。如果类支持序列化,那么另一种hackish方法是序列化对象,然后保存反序列化的副本。但是,如果可以修复可变对象的设计,那将是一种更好的方法。

修改
对于您给出的特定示例,Romain的答案可以满足您的需求。如果你有一个普通的可变对象,它不提供复制它的机制,并且直到以后才能知道这种类型,那么反射方法就是如何实现复制机制。