Comparison of Ways to Check Preconditions in Java

BY MARKUS SPRUNCK

This article focuses on preconditions which are directly part of the source code. It doesn't cover other approaches which use annotations and aspect oriented programming.

Motivation

The use of preconditions, post-conditions and invariants is extremely helpful to develop maintainable code. Unfortunately, we find preconditions quite seldom in real world applications. In some cases you can read correct preconditions in JavaDoc comments.

Two disadvantages of JavaDoc comments are that: (i) they just get outdated in cases the implementation changes and (ii) most of the developers just don't read them or read them too late.

Example Code

In the example code you may see four different ways to directly implement preconditions and the use of asserts (run the code with VM option -ea to enable asserts).

Find Code on GitHub

Dependencies

To compile the code (see link below) you will need the following libraries:

Summary

Usage of Plain Java Validation

Description:

  • Check the needed condition and throw the appropriate exception

Advantage:

  • Works always without additional external libraries

Disadvantage:

  • Needs a lot of code.
  • Message string can not use parameters

Example:

Usage of Guava Preconditions

Description:

The class Preconditions may throw:

  • IllegalArgumentException
  • NullPointerException
  • IllegalStateException
  • IndexOutOfBoundsException

Advantage:

  • Message string can use parameters
  • Works with GWT

Disadvantage:

  • footprint very large

Example:

Usage of Apache Commons Validate

Description:

The class Validate may throw:

  • NullPointerException
  • IllegalArgumentException
  • IndexOutOfBoundsException

Advantage:

  • Message string can use parameters

Disadvantage:

  • footprint larg

Example:

Usage of Spring Framework Assert

Description:

The class Validate may throw:

  • IllegalArgumentException
  • IllegalStateException

Advantage:

  • Automatically part of applications which use Spring framework

Disadvantage:

  • Message string can not use parameters
  • Just basic functionality

Example:

Usage of Plain Java Asserts

Description:

  • Don't use assertions to do work that your application requires for correct operation in business logic.
  • If the condition is false, the assert throws an AssertionError with just the message text.
  • Must be enabled during run time with VM option.

Advantage:

  • Good for checks during development and for documentation purposes
  • May be a source of errors if business logic is part of asserts.

Disadvantage:

  • An assertion failure will never throw an appropriate exceptions, everything is just an AssertionError.
  • Message string can not use parameters.

Example:

Expected Output

When you run the sample code something like this is the output:

Recommendations

  • Use Preconditions in your code, this is most of the time better than a lot of comments, but don't use asserts as preconditions.
  • But, I can't recommend assert to check preconditions, but you may mix asserts with the four other approaches.
  • Guava Preconditions and Apache Commons Validate class are the best choice. They have almost the same functionality, just take what is more convenient in your technology stack.