DEFENSIVE PROGRAMMING WITH KLOJANG CHECK

Performance

You probably noticed the fluent API in the introductory code example. That implies that there must be some object creation going on. So, to address that worry right away: benchmarking Klojang Check using JMH yields no difference with hand-coded checks. You can view the results of the benchmarks here.

Looking at the code example, that should not be surprising. The object creation is completely localized and, in fact, redundant. The object created by Check.that(...) never gets assigned. It is gone by the time the next statement executes. Consequently, the JVM has no trouble compiling it away altogether.

We Don't Check Your Check

Perhaps paradoxically, while Klojang Check is all about ensuring your method's preconditions are met before doing anything else, Klojang Check itself does no such thing. Take, for instance, this statement:

Check.that(fullName).is(hasSubstring(), lastName);

The  hasSubstring() check simply wraps  String::contains, so this statement will fly off the rails with a NullPointerException if any of the provided arguments is null. Yet, Klojang Check will not perform a null check on any of them. That sounds like a bad case of Do As I Say, Not As I Do. We think it is justified, however. In the (rather) odd case that the check to be executed is dynamically inserted into the is(...) method, the check itself becomes program input! Hence, it needs to be validated just like anything else entering your program — and we can warmly recommend a library to help you with that. As for the fullName argument, which is the value we are testing: if it could possibly be null, you should always first perform a null check:

Check.notNull(fullName).is(hasSubstring(), lastName);

Klojang Check provides a syntactical mould for you to "pour" your tests into, but in the end it is still you who decides which tests to execute and in which order. If each and every check would automatically be supplemented with three or four more checks, just to verify that the original check was specified correctly, that would raise the cost of doing a check to a level that would likely be unacceptable for many developers.