The idea is to fail quickly. For example, consider this silly class:
public class Foo { private final String s; public Foo(String s) { this.s = s; } public int getStringLength() { return s.length(); } }
Say you do not want to allow null values for s . (otherwise getStringLength will throw an NPE). With the as-is class, by the time you realize that null is too late, it is very difficult to figure out who put it there. The culprit could well have been in a completely different class, and that the Foo example could have been built a long time ago. Now you need to comb your code base to find out who could put the null value there.
Imagine this constructor instead:
public Foo(String s) { this.s = checkNotNull(s); }
Now, if someone puts null there, you will know right away - and you will have a stack trace indicating that you really made a mistake.
Another time, this can be useful if you want to check the arguments before taking actions that can change state. For example, consider this class, which calculates the average of all the lengths of the strings it receives:
public class StringLengthAverager { private int stringsSeen; private int totalLengthSeen; public void accept(String s) { stringsSeen++; totalLengthSeen += s.length(); } public double getAverageLength() { return ((double)totalLengthSeen) / stringsSeen; } }
Calling accept(null) will cause the NPE to be reset - but not before the stringsSeen been incremented. Perhaps this is not what you want; as a user of the class, I can expect that if it does not accept NULL values, then its state should not change if you pass zero (in other words: the call should fail, but it should not deprive the object). Obviously, in this example, you can also fix this by getting s.length() before increasing stringsSeen , but you can see how, for a longer and more complex method, it may be useful to first verify that all your arguments are valid, and only then change state:
public void accept(String s) { checkNotNull(s);
yshavit Oct 03 '14 at 18:16 2014-10-03 18:16
source share