这是有效Java中的防御性复制示例。假设场景在我的基本问题中需要防御性的副本,并且不能与要求客户避免对传入的对象进行变异的注释无关。

public Period(Date start, Date end) {
    this.start = new Date(start.getTime());
    this.end = new Date(end.getTime());
}

问题:
  • 如果Date没有构造函数可以使用,为了使我的自我更笼统,传递了一个没有任何机制来复制自身的对象,并且该对象不属于我们,即我们无法在任何情况下更改它,该怎么办方式 ?
  • 如果构造函数将类型参数作为参数,那Period(T object)和T可能是可变的,那么需要防御性副本。我们不知道什么是T。在这种情况下,如何进行防御性复制?
  • 传递了什么接口,其中某些子类确实具有类似于Date的构造函数来创建其自身的对象,而其某些子类却没有任何机制来这样做?
  • 我们应该防御复制多深?可以说我们复制了一个数组,但是数组元素是可变的?
  • 最佳答案

  • 如果所有状态均可用,则可以自己提取其状态并构造一个新对象。否则,除了使用讨厌的反射或序列化技巧外,您将无能为力。
  • 如果T不是允许复制自身的类的实例,则您将无法执行任何操作。
  • 您无能为力。
  • 这取决于。

  • 通过阅读您的问题,您似乎想在各处应用“防御性副本”建议。你不应该大多数情况下,使用可变对象的代码需要引用原始对象,而不是副本。特别是当您作为参数获得的是抽象类或接口的实例时。

    您被迫制作Date的防御性副本,因为它是可变的值类型,不应可变,并且如果其设计正确,也不会。如果您为值类型提倡不变性,那么防御性副本就变得不必要了。对于非值类型,通常不需要副本,而需要引用对象。

    10-08 12:56