In Josh Bloch’s excellent book Effective Java under Item 39 he says:
“[D]efensive copies are made before checking the validity of the parameters, and the validity check is performed on the copies rather than on the originals.”
The example given is as follows:
public Period(Date start, Date end) {
this.start = new Date(start.getTime());
this.end = new Date(end.getTime());
if(this.start.compareTo(this.end) > 0)
throw new IllegalArgumentException("...");
}
}
The problem with doing the validity checks after the defensive copy is that an invalid parameter can cause the creation of the copy to fail. For example, the class above will throw a NullPointerException if you pass it a null for start or end.
If I move the validity check before the defensive copy, I am vulnerable to the time-of-check/time-of-use attack that Bloch cites as the reason for doing the defensive copy first.
My question is what is a way around this? I can’t believe I’m the first person to see this problem in a well read book (though the errata for the book says nothing about it), so maybe I’m just missing something.
As others said, you check for
nullbefore copying the parameters.No, a hacker won’t be able to change a reference to an actual instance to a null reference, or vice-versa. The copying is done to avoid changes to the internal state of the arguments from another thread.