Java 如何处理防御性编程的各种情况?
这是一个有效java中的防御复制示例。假设我的基本问题中的场景需要一个防御性副本,而不能使用注释要求客户端避免对传入的对象进行变异Java 如何处理防御性编程的各种情况?,java,generics,constructor,defensive-copy,Java,Generics,Constructor,Defensive Copy,这是一个有效java中的防御复制示例。假设我的基本问题中的场景需要一个防御性副本,而不能使用注释要求客户端避免对传入的对象进行变异 public Period(Date start, Date end) { this.start = new Date(start.getTime()); this.end = new Date(end.getTime()); } 问题: 如果Date没有一个构造函数来容纳它自己,那么该怎么办呢?为了使我自己更一般,一个对象在传递时没有复制它自己的
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
)来创建它自己的对象,而它的一些子类没有任何机制来创建对象时,传递什么是接口当传递给方法的对象是可变的时,防御性编程很重要。一个好的实践(也在有效的Java书籍中描述)是使它们不可变
我会说,在某些情况下,这种情况会变成一种代码气味。对于一个复杂的对象,这意味着你在某个地方保存状态,我会考虑取消状态保存。在所有情况下,这不是正确的做法,但在任何情况下都应该提出这个问题。至于当你真的需要这样做的时候,我会说你不得不手工编写定制的复制代码,或者定义一些新的小的、不可变的对象,只复制它实际需要的数据。记住,这些不是严格的通用规则。这要视情况而定。你不应该刻意复制所有的参数(我会在这个基础上拒绝你的代码),当你做不好的时候,要么改变代码(如果它真的需要是一个不可变的对象),要么就让它去做。你还应该检查开始和结束日期是否为空。如果你不这样做,你可能会得到一个NullPointerException。@Gynnad:如果日期是强制性的,抛出NullPointerException是正确的做法。这个建议在理论上听起来不错,但在现实生活中,实现我自己的
Date
包装器相当麻烦。我不确定最后两个对这个问题有什么意义。unmodifiableX
方法必须在类外使用;它们作为防御复制机制是无用的,因为底层对象可以在类之外修改。它们旨在防止其他对象修改代码生成的数据,这在某种程度上与防御性复制相反。同步与防御性复制是不同的问题。(只是解释我的反对票。)