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.