When should I use Apache Commons' Validate.isTrue, and when should I just use the 'assert' keyword?
Do not use assertions to check the parameters of a public method. An assert is inappropriate because the method guarantees that it will always enforce the argument checks. It must check its arguments whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type.
An assertion is a statement in Java which ensures the correctness of any assumptions which have been done in the program. When an assertion is executed, it is assumed to be true. If the assertion is false, the JVM will throw an Assertion error. It finds it application primarily in the testing purposes.
Assertions are used to codify the requirements that render a program correct or not by testing conditions (Boolean expressions) for true values, and notifying the developer when such conditions are false. Using assertions can greatly increase your confidence in the correctness of your code.
An assertion is made using the assert keyword. Its syntax is: assert condition; Here, condition is a boolean expression that we assume to be true when the program executes.
Assertions can be turned off (in fact, they normally are), so they are not useful for validating user input, for example.
Validate.isTrue and 'assert' serve completely different purposes.
assert
Java's assert statements are typically used for documenting (by means
of assertions) under what circumstances methods can be invoked, and
what their callers can expect to be true afterward. The assertions can
optionally be checked at run time, resulting in an AssertionError
exception if they don't hold.
In terms of design-by-contract, assertions can be used to define pre- and postconditions as well as class invariants. If at run time these are detected not to hold, this points to a design or implementation problem in the system.
Validate.isTrue
org.apache.commons.lang.Validate is different. It offers a simple set
of JUnit-like methods which check a condition, and throw an
"IllegalArgumentException" if the condition does not hold.
It is typically used when a public API should be tolerant against bad input. In that case, its contract can promise to throw an IllegalArgumentException upon erroneous input. Apache Validate offers a convenient shorthand for implementing this.
Since an IllegalArgumentException is thrown, it does not make sense to use Apache's Validate to check postconditions or invariants. Likewise, it is incorrect to use 'assert' for user input validation, since assertion checking can be disabled at run time.
Using both
It is possible, though, to use both at the same time, albeit
for different purposes. In this case, the contract should explicitly
require IllegalArgumentException to be raised upon certain types
of input. This is then implemented via Apache Validate.
Invariants and postconditions are then simply asserted, as well
as possible additional preconditions (for example affecting the
state of the object). For example:
public int m(int n) {
// the class invariant should hold upon entry;
assert this.invariant() : "The invariant should hold.";
// a precondition in terms of design-by-contract
assert this.isInitialized() : "m can only be invoked after initialization.";
// Implement a tolerant contract ensuring reasonable response upon n <= 0:
// simply raise an illegal argument exception.
Validate.isTrue(n > 0, "n should be positive");
// the actual computation.
int result = complexMathUnderTrickyCircumstances(n);
// the postcondition.
assert result > 0 : "m's result is always greater than 0.";
assert this.processingDone() : "processingDone state entered after m.";
assert this.invariant() : "Luckily the invariant still holds as well.";
return result;
}
More information:
@thilo is right for assert keyword, but consider about Assertion like spring Assert.
See ConditionalFailuresExplained from Guava.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With