Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll show how to use the Google Guava’s Preconditions class.

The Preconditions class provides a list of static methods for checking that a method or a constructor is invoked with valid parameter values. If a precondition fails, a tailored exception is thrown.

2. Google Guava’s Preconditions

Each static method in the Preconditions class has three variants:

  • No arguments. Exceptions are thrown without an error message
  • An extra Object argument acting as an error message. Exceptions are thrown with an error message
  • An extra String argument, with an arbitrary number of additional Object arguments acting as an error message with a placeholder. This behaves a bit like printf, but for GWT compatibility and efficiency it only allows %s indicators

Let’s have a look at how to use the Preconditions class.

2.1. Maven Dependency

Let’s start by adding Google’s Guava library dependency in the pom.xml:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.1.3-jre</version>
</dependency>

The latest version of the dependency can be checked here.

3. checkArgument

The method checkArgument of the Preconditions class ensures the truthfulness of the parameters passed to the calling method. This method accepts a boolean condition and throws an IllegalArgumentException when the condition is false.

Let’s see how we can use this method with some examples.

3.1. Without an Error Message

We can use checkArgument without passing any extra parameter to the checkArgument method:

@Test
public void whenCheckArgumentEvaluatesFalse_throwsException() {
    int age = -18;
 
    assertThatThrownBy(() -> Preconditions.checkArgument(age > 0))
      .isInstanceOf(IllegalArgumentException.class)
      .hasMessage(null).hasNoCause();
}

3.2. With an Error Message

We can get a meaningful error message from the checkArgument method by passing an error message:

@Test
public void givenErrorMsg_whenCheckArgEvalsFalse_throwsException() {
    int age = -18;
    String message = "Age can't be zero or less than zero.";
 
    assertThatThrownBy(() -> Preconditions.checkArgument(age > 0, message))
      .isInstanceOf(IllegalArgumentException.class)
      .hasMessage(message).hasNoCause();
}

3.3. With a Template Error Message

We can get a meaningful error message along with dynamic data from the checkArgument method by passing an error message:

@Test
public void givenTemplateMsg_whenCheckArgEvalsFalse_throwsException() {
    int age = -18;
    String message = "Age should be positive number, you supplied %s.";
 
    assertThatThrownBy(
      () -> Preconditions.checkArgument(age > 0, message, age))
      .isInstanceOf(IllegalArgumentException.class)
      .hasMessage(message, age).hasNoCause();
}

4. checkElementIndex

The method checkElementIndex checks that an index is a valid index in a list, string or an array of a specified size. An element index may range from 0 inclusive to size exclusive. You don’t pass a list, string or array directly, you just pass its size. This method throws an IndexOutOfBoundsException if the index is not a valid element index, else it returns an index that’s being passed to the method.

Let’s see how we can use this method by showing a meaningful error message from the checkElementIndex method by passing an error message when it throws an exception:

@Test
public void givenArrayAndMsg_whenCheckElementEvalsFalse_throwsException() {
    int[] numbers = { 1, 2, 3, 4, 5 };
    String message = "Please check the bound of an array and retry";
 
    assertThatThrownBy(() -> 
      Preconditions.checkElementIndex(6, numbers.length - 1, message))
      .isInstanceOf(IndexOutOfBoundsException.class)
      .hasMessageStartingWith(message).hasNoCause();
}

5. checkNotNull

The method checkNotNull checks whether a value supplied as a parameter is null. It returns the value that’s been checked. If the value that has been passed to this method is null, then a NullPointerException is thrown.

Next, we are going to show how to use this method by showing how to get a meaningful error message from the checkNotNull method by passing an error message:

@Test
public void givenNullString_whenCheckNotNullWithMessage_throwsException () {
    String nullObject = null;
    String message = "Please check the Object supplied, its null!";
 
    assertThatThrownBy(() -> Preconditions.checkNotNull(nullObject, message))
      .isInstanceOf(NullPointerException.class)
      .hasMessage(message).hasNoCause();
}

We can also get a meaningful error message based on dynamic data from the checkNotNull method by passing a parameter to the error message:

@Test
public void whenCheckNotNullWithTemplateMessage_throwsException() {
    String nullObject = null;
    String message = "Please check the Object supplied, its %s!";
 
    assertThatThrownBy(
      () -> Preconditions.checkNotNull(nullObject, message, 
        new Object[] { null }))
      .isInstanceOf(NullPointerException.class)
      .hasMessage(message, nullObject).hasNoCause();
}

6. checkPositionIndex

The method checkPositionIndex checks that an index passed as an argument to this method is a valid index in a list, string or array of a specified size. A position index may range from 0 inclusive to size inclusive. You don’t pass the list, string or array directly, you just pass its size.

This method throws an IndexOutOfBoundsException if the index passed is not between 0 and the size given, else it returns the index value.

Let’s see how we can get a meaningful error message from the checkPositionIndex method:

@Test
public void givenArrayAndMsg_whenCheckPositionEvalsFalse_throwsException() {
    int[] numbers = { 1, 2, 3, 4, 5 };
    String message = "Please check the bound of an array and retry";
 
    assertThatThrownBy(
      () -> Preconditions.checkPositionIndex(6, numbers.length - 1, message))
      .isInstanceOf(IndexOutOfBoundsException.class)
      .hasMessageStartingWith(message).hasNoCause();
}

7. checkState

The method checkState checks the validity of the state of an object and is not dependent on the method arguments. For example, an Iterator might use this to check that next has been called before any call to remove. This method throws an IllegalStateException if the state of an object (boolean value passed as an argument to the method) is in an invalid state.

Let’s see how we can use this method by showing a meaningful error message from the checkState method by passing an error message when it throws an exception:

@Test
public void givenStatesAndMsg_whenCheckStateEvalsFalse_throwsException() {
    int[] validStates = { -1, 0, 1 };
    int givenState = 10;
    String message = "You have entered an invalid state";
 
    assertThatThrownBy(
      () -> Preconditions.checkState(
        Arrays.binarySearch(validStates, givenState) > 0, message))
      .isInstanceOf(IllegalStateException.class)
      .hasMessageStartingWith(message).hasNoCause();
}

8. Conclusion

In this tutorial, we illustrated the methods of the PreConditions class from the Guava library. The Preconditions class provides a collection of static methods that are used to validate that a method or a constructor is invoked with valid parameter values.

The code belonging to the above examples can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as is.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are closed on this article!