DEFENSIVE PROGRAMMING WITH KLOJANG CHECK
Custom Checks
You are, of course, not limited to using the checks from the CommonChecks class. You can provide your own checks in the form of lambdas and method references:
Check.that(angle).is(a -> Math.sin(a) > 0, "sine of angle must be positive");
Be careful, however, when passing lambdas and method references to the has() and notHas() methods. These methods are heavily overloaded. Therefore, "vanilla" lambdas (as you would habitually write them) and method references may cause the compiler to complain about an Ambiguous method call:
// WON'T COMPILE! Ambiguous method call
Check.that(-7).has(i -> Math.abs(i), i -> i == 7);
The solution is to specify the type of the lambda parameter, or to cast the entire lambda or method reference. This will give the compiler enough context to decide which of the overloaded has() and notHas() methods to choose.
// specify the type of the lambda parameter:
Check.that(-7).has(i -> Math.abs(i), (int i) -> i == 7);
// cast the lambda that extracts the property from the argument:
Check.that(-7).has((IntUnaryOperator) i -> Math.abs(i), i -> i == 7);
// cast the method reference that extracts the property from the argument:
Check.that(-7).has((IntUnaryOperator) Math::abs, i -> i == 7);
// cast the lambda that tests the property:
Check.that(-7).has(i -> Math.abs(i), (IntPredicate) i -> i == 7);
If you don't like the verbosity that now suddenly creeps into your checks, you could write your own CommonChecks-like class:
public class MyCommonChecks {
public static ComposableIntPredicate equalToSeven() {
return i -> i == 7;
}
}
Check.that(-7).has(i -> Math.abs(i), equalToSeven());