这是Effective 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
这样的构造函数来创建自己的对象,而它的一些子类没有任何机制可以这样做?
我们应该在多大程度上防御性地复制?让我们说我们复制一个数组,但数组元素是可变的?
答案 0 :(得分:2)
通过阅读您的问题,您似乎希望在任何地方应用“防御性副本”建议。你不应该。大多数情况下,使用可变对象的代码需要引用原始对象,而不是副本。特别是如果你得到的参数是抽象类或接口的实例。
你被迫制作一个Date的防御性副本,因为它是不可变的可变值类型,如果设计得当,则不会。如果您提升价值类型的不变性,那么防御性副本就变得不必要了。对于非值类型,通常不需要副本,而是对对象的引用。
答案 1 :(得分:0)
答案 2 :(得分:0)
当您传递给方法的对象是可变的时,防御性编程很重要。一个好的做法(在Effective Java书中也有描述)是使它们不可变。