When should I use Apache Commons' Validate.isTrue, and when should I just use the 'assert' keyword?
Asked Answered
P

3

14

When should I use Apache Commons' Validate.isTrue, and when should I just use the 'assert' keyword?

Pagoda answered 19/2, 2011 at 5:55 Comment(1)
possible duplicate of On Asserts and Exceptions; JavaMuscular
S
6

Assertions can be turned off (in fact, they normally are), so they are not useful for validating user input, for example.

Sideline answered 19/2, 2011 at 6:10 Comment(1)
I would add that they are all used to enforce the contractual obligations of our objects (or APIs, which IMO are just another way to implement object oriented programming). Using the assert statement should be reserved for computations that are EXPENSIVE and we want to turn on only during testing or debugging (not in production).Eldridgeeldritch
U
35

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:

  • Bertrand Meyer, "Applying Design by Contract", IEEE Computer, 1992 (pdf)
  • Johsua Bloch. Effective Java, 2nd ed., Item 38. Check parameters for validity. (google books)
Unanimous answered 27/3, 2011 at 20:49 Comment(3)
Johsua Bloch. Effective Java, Item 23: Check parameters for validity.Decemvir
What about Spring's assertions like Assert.notNull()?Beerbohm
The Spring documentation suggests that its Assert class is "Mainly for internal use within the framework", recommending to use, e.g., commons.lang3.validate instead. So similar to Apache commons, also in that it can't be switched off at run time. docs.spring.io/spring-framework/docs/current/javadoc-api/org/…Unanimous
S
6

Assertions can be turned off (in fact, they normally are), so they are not useful for validating user input, for example.

Sideline answered 19/2, 2011 at 6:10 Comment(1)
I would add that they are all used to enforce the contractual obligations of our objects (or APIs, which IMO are just another way to implement object oriented programming). Using the assert statement should be reserved for computations that are EXPENSIVE and we want to turn on only during testing or debugging (not in production).Eldridgeeldritch
M
2

@thilo is right for assert keyword, but consider about Assertion like spring Assert.

See ConditionalFailuresExplained from Guava.

  • Precondition "You messed up (caller)."
  • Assertion "I messed up."
  • Verification "Someone I depend on messed up."
Mediatize answered 23/3, 2016 at 3:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.