As per Josh Bloch's Effective java :-
do not use the clone method to make a defensive copy of a parameter whose type is subclassable by untrusted parties.
Now taking a expert from his book only:-
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
}
I do not get what wrong would happen if I modify a accesor method to return a copy of date object using clone function instead of copy using constructor like this :-
public Date start() {
return start.clone();
}
instead of
public Date start() {
return new Date(start.getTime());
}
How possibly can a instance of malicious subclass be returned?
Take the java.util.Date class which provides a defensive copy in its clone() method but which is also not final.
Suppose I subclass Date and I override theclone() method.
Now, at runtime, if I receive an instance of this subclass, clone() of Date is not used anylonger. So, I am not sure that the implementation of the child class makes still a defensive copy as the original.
This :
public Date start() {
return start.clone();
}
will not be a defensive copy if a subclass overrides clone() like that :
@Override
public Object clone() {
return this;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With