7.39 必要时使用保护性复制(defensive copy)
以下Period类用于表示两个日期之间的间隔:
?
public class Period {//使用不可变的数据类型private long start;private long end;public Period(Date start,Date end){this.start=start.getTime();this.end=end.getTime();if(this.start>this.end)throw new IllegalArgumentException("start after end");}public boolean isValid(){return start<=end;}public Date getStart() {return new Date(start);}public Date getEnd() {return new Date(end);}}
?
?
如果不希望外部修改引起类的属性的变化,但是属性的数据类型又是Date,Array,Collection,Map等可变类型,那么应使用保护性复制,使用原则如下:
1.在校验输入参数前进行保护性复制
2.如果属性类型是可变的,在返回给调用者前应进行保护性复制
3.不要使用clone()进行保护性复制,clone()可能返回子类对象,可能导致恶意攻击
?
保护性复制和不可变类一样都可能引起性能问题,如果不能使用保护性复制,同时又希望外部修改不引起属性变化,那么应在注释里详细说明,告诉调用者不要进行可能引起属性值改变的修改。
?
?
?
?
?
?
?
?