【发布时间】:2016-11-29 09:58:46
【问题描述】:
根据 Josh Bloch 的 Effective java :-
不要使用 clone 方法制作参数的防御性副本 其类型可被不受信任的方子类化。
现在只从他的书中挑选一位专家:-
public final class Period {
private final Date start;
private final Date end;
/**
* @param start the beginning of the period
* @param end the end of the period; must not precede start
* @throws IllegalArgumentException if start is after end
* @throws NullPointerException if start or end is null
*/
public Period(Date start, Date end) {
if (start.compareTo(end) > 0)
throw new IllegalArgumentException(
start + " after " + end);
this.start = start;
this.end = end;
}
public Date start() {
return start;
}
public Date end() {
return end;
}
... // Remainder omitted
}
如果我修改访问器方法以使用克隆函数返回日期对象的副本,而不是使用像这样的构造函数进行复制,我不明白会发生什么错误:-
public Date start() {
return start.clone();
}
而不是
public Date start() {
return new Date(start.getTime());
}
恶意子类的实例怎么可能被返回?
【问题讨论】:
-
由于 Date 不是 Final 类,因此 clone() 不能保证返回对象的防御性副本。