Java Assertions

In this tutorial we will look at Java assertions which are realized with the Java assert keyword. Java assertions allows the testing of the correctness of any assumptions made or the expected state of a piece of code within a program. If an assertion is found not to be true the JVM will throw an AssertionError. Assertions are mainly used during development and turned off in production.

What Are Java Asssertions

Java assertions were introduced in Java 1.4 and can be implemented in code using the Java assert keyword. Java assertions are a useful tool that can catch programming errors early during development. An assert statement is used with a boolean expression, and the boolean expression must evaluate to true for the assertion to pass.

For example consider we are writing some code to determine if a Java class is a collection:

1
2
3
4
5
6
public static boolean isCollection(Class<?> clazz) {
    if (clazz == null) {
        throw new IllegalArgumentException("clazz is required");
    }
    return Collection.class.isAssignableFrom(clazz);
}

We can simplify the above code by using a Java assert statement:

1
2
3
4
public static boolean isCollection(Class<?> clazz) {
    assert clazz != null : " clazz is required";
    return Collection.class.isAssignableFrom(clazz);
}

It should also be noted that this is not the only way we could handle this scenario in our code, if it was decided not to use assertions we could create a utility class called AssertUtils to test for these scenarios. This approach of using the AssertUtils class is preferred when asserting input parameters or conditions in a public method, as it is something that the client of the public method should be made aware of.

1
2
3
4
5
6
7
8
public class AssertUtils {

    public static void notNull(Object object, String message) {
        if (object == null) {
            throw new IllegalArgumentException(message);
        }
    }
}
1
2
3
4
public static boolean isCollectionWithUtils(Class<?> clazz) {
    AssertUtils.notNull(clazz, "clazz is required");
    return Collection.class.isAssignableFrom(clazz);
}

Java Assert Statement

There are different forms of the Java assert statement. The assert statement takes a boolean expression and we can create it in different ways. For example we can create an assert statement as follows:

1
assert expression;

or we can use an alternative form:

1
assert expression1 : expression2;

Enabling Java Assertions

Java assertions are disabled by default. Moreover, to use assertions within our code using the assert keyword we do not have to import any third part dependencies. Also, since from Java 1.4 we can no longer use the assert keyword as variable, method, package names etc.

There to use Java assertions in our code they must be enabled. They must be explicitly enabled using either the -enableassertions command line argument, or -ea for short:

1
java -ea com.stephenenright.tutorials.corejava.assertion.AssertionExample

or:

1
java –enableassertions com.stephenenright.tutorials.corejava.assertion.AssertionExample

We can also enable assertions for specific packages and classes:

1
java -ea:com.stephenenright.tutorials.corejava.assertion … com.stephenenright.tutorials.corejava.assertion.AssertionExample

Assertions can also be disabled following a similar approach:

1
java –da com.stephenenright.tutorials.corejava.assertion.AssertionExample
1
java –disableassertions com.stephenenright.tutorials.corejava.assertion.AssertionExample

Why Use Java Assertions

Assertions are useful when a developer wants to assert if their assumptions are correct. Some of the reasons for using assertions include:

  • To ensure pre-conditions of a method are correct, such as input variables not being null or empty.
  • To assert assumptions written in comments.
  • To assert an object’s state

Using Java Assertions

To use assertions in our code as shown previously we use the assert keyword with a boolean expression.

1
2
3
4
public static boolean isCollection(Class<?> clazz) {
    assert clazz != null;
    return Collection.class.isAssignableFrom(clazz);
}

There is also a second form of the assertion statement that if provided will be used to create the text of the assertion if the assertion fails.

1
2
3
4
public static boolean isCollection(Class<?> clazz) {
    assert clazz != null : " clazz is required";
    return Collection.class.isAssignableFrom(clazz);
}

In the above two examples the code is checking that the clazz parameter is not null. If the clazz parameter is null and we have assertions enabled we will receive an AssertionError and the program will terminate.

1
2
3
4
5
Exception in thread "main" java.lang.AssertionError: Connection is null
    at com.stephenenright.tutorials.corejava.assertion
.AssertionExample.isCollection(AssertionExample.java:7)
    at com.stephenenright.tutorials.corejava.assertion
.AssertionExample.main(AssertionExample.java:19

Assertions And Exception Handling

Typically we should not handle an AssertionError or try to recover from it. An assertion error indicates an unrecoverable error. In the Java exception hierarchy AssertionError extends Error. Moreover, AssertionError is a runtime exception.

Therefore methods are not required to handle assertion errors at compile time. Moreover, unlike normal exception handling, assertions are normally disabled at runtime, so handling them may be overkill.

Assertion Best Practices

One of the most important considerations as we mentioned before is that assertions are normally disabled so we should never try to handle them following traditional exception handling techniques.

Where To Use Assertions

Some examples of where to use assertions include:

  • checking for null and empty values.
  • use in places that will never be executed, such default case in a switch statement.
  • Conditions at the beginning of any method.
  • Private method arguments are a good use case.

Where Not To Use Assertions

Some places where not to use assertions include:

  • They should not be used to replace exception handling techniques.
  • They should not be used to replace errors that a client should be notified about.
  • They should not replace error messages.
  • Do not use assertions to check invalid input in a public method instead use exceptions such as IllegalArgumentException using something like the AssertUtils class that we showed earlier.

Conclusion

The Java assert keyword is a mechanism that allows us to test assumptions within our code. Moreover, it can reduce boilerplate code, however we must be careful not to use it with public methods that need to report errors to client code.