Introduction
The Validate class in the Apache Commons Lang library helps in validating arguments to a method (or a constructor). In this post we will learn about the utility methods in the Apache Commons Lang Validate class.
Apache Commons Validate
When we write a method (or a constructor), there is often a need to validate the arguments passed in. For example, we have a setAge method as shown below:
public void setAge(int age) {
....
}
We must validate that the age is greater than 0 and lesser than some upper bound (say 100).
The Apache Commons Validate class offers many classes of static utility methods to validate arguments. If the validation of the arguments fails, it could throw one of the three exceptions (depending on the method we call):
- IllegalArgumentException
- IllegalStateException
- IndexOutOfBoundsException
- NullPointerException
Many methods in the Validate class accept exception messages. These are format strings.
In this post, to explain the methods in the Apache Commons Lang Validate class, I’ll be passing explicitly created objects (like an array, empty list etc.,). But in real application of this, we would be passing the arguments to a method or a constructor as seen before.
Validate notNull
The notNull method takes an argument and throws a NullPointerException if the passed argument is null. The default exception message is The validated object is null.
We can also pass an exception message as,
Validate.notNull(null, "The passed value is null");
//or with static import
notNull(null, "The passed value is null");
Validate notEmpty
There are many overloaded version of the notEmpty method which accept an array, collection, map or a CharSequence. Each of these methods come in two flavours: one that has a default exception message and one to which we can pass an exception message format string.
The notEmpty method checks if the passed array/collection/map/CharSequence is neither null nor empty. If it is null or empty, it throws an IllegalArgumentException. Shown below are the usage of notEmpty passing an empty array.
//throws java.lang.IllegalArgumentException: The validated array is empty
notEmpty(new String[]{});
//throws java.lang.IllegalArgumentException: The passed array is empty
notEmpty(new String[]{}, "The passed array is empty");
For a collection,
//throws java.lang.IllegalArgumentException: The validated collection is empty
notEmpty(List.of());
//throws java.lang.IllegalArgumentException: The passed list is empty
notEmpty(List.of(), "The passed list is empty");
For a map, it checks if the map is not null and it has at least one entry - if not, it throws an IllegalArgumentException.
// throws java.lang.IllegalArgumentException: The validated map is empty
notEmpty(Map.of());
//throws java.lang.IllegalArgumentException: The passed map is empty
notEmpty(Map.of(), "The passed map is empty");
Similarly, for a CharSequence,
// throws java.lang.IllegalArgumentException: The validated character sequence is empty
notEmpty("");
// throws java.lang.IllegalArgumentException: The validated string is empty
Validate.notEmpty("", "The passed string is empty");
Validate notBlank
The notBlank method takes a character sequence and ensures it is not
- null
- of length zero
- empty
- whitespace
If it violates one of the above checks (if it is null/of length 0/empty/has only whitespace characters), it throws an IllegalArgumentException.
// throws java.lang.IllegalArgumentException: The validated character sequence is blank
notBlank(" ");
// throws java.lang.IllegalArgumentException: The string is blank
notBlank(" ", "The string is blank");
Validate noNullElements
The noNullElements works on an Iterable or an array and it ensures that the passed Iterable/Array is not null and has no null elements in them.
The exception message states the position at which the (first) null element was found.
// java.lang.IllegalArgumentException: The validated array contains null element at index: 1
noNullElements(new String[]{"a", null, "b"});
// java.lang.IllegalArgumentException: The validated collection contains null element at index: 1
noNullElements(list);
//java.lang.IllegalArgumentException: The list has null elements
noNullElements(list, "The list has null elements");
Validate validIndex
The validIndex method accepts either a collection, an array or a CharSequence and an index and checks if the passed index is a valid index (within bounds).
//java.lang.IndexOutOfBoundsException: The validated array index is invalid: 2
validIndex(new String[]{"a", "b"}, 2);
The above code snippet throws an exception as index 2 is not within the bounds [0, 1]. Similarly, for a CharSequence and a collection,
//java.lang.IndexOutOfBoundsException: The validated character sequence index is invalid: 4
validIndex("abcd", 4);
List<String> list = Arrays.asList("a", "b");
//java.lang.IndexOutOfBoundsException: The validated collection index is invalid: 10
validIndex(list, 10);
Validate isTrue and validState
Validate#isTrue
The isTrue method takes a boolean value and validates if it is true; otherwise throws an exception.
(say age is -1)
//throws java.lang.IllegalArgumentException: The validated expression is false
isTrue(age > 0);
To have a meaningful exception message, we can pass a format string as shown below:
// java.lang.IllegalArgumentException: The passed age -1 is invalid
isTrue(age > 0, "The passed age %d is invalid", age);
Validate#validState
The validState method is similar to the isTrue method, but it throws an IllegalStateException when the boolean is false.
// java.lang.IllegalStateException: The validated state is false
validState(age > 0);
// java.lang.IllegalStateException: The passed age -1 is invalid
validState(age > 0, "The passed age %d is invalid", age);
Validate notNaN and finite
Validate notNaN
This method validates that the passed argument is not NaN.
// java.lang.IllegalArgumentException: The validated value is not a number
notNaN(Double.NaN);
// java.lang.IllegalArgumentException: The double argument is NaN
notNaN(Double.NaN);
Validate finite
The finite method validates that the passed argument is not infinite or NaN.
// java.lang.IllegalArgumentException: The value is invalid: NaN
finite(Double.NaN);
// java.lang.IllegalArgumentException: The value is invalid: Infinity
finite(Double.POSITIVE_INFINITY);
// java.lang.IllegalArgumentException: The value is invalid: -Infinity
finite(Double.NEGATIVE_INFINITY);
Validate inclusiveBetween
The inclusiveBetween method takes two values and an argument and checks if the argument falls between the two (inclusive) values passed. This method is overloaded to work for a long, double and arbitrary type T (of type Comparable). The range values passed are inclusive.
No exception is thrown for the below calls:
inclusiveBetween(1L, 3L, 1L);
inclusiveBetween(1D, 3D, 1D);
inclusiveBetween("a", "g", "b");
In the first two calls, value 1 lies between the range [1, 3]. In the last call, the string b is between the range [a, g].
On the other hand, shown below are the cases where it throws an exception. The exception message specifies the range and the passed argument.
// java.lang.IllegalArgumentException: The value 4 is not in the specified inclusive range of 1 to 3
inclusiveBetween(1L, 3L, 4L);
// java.lang.IllegalArgumentException: The value z is not in the specified inclusive range of a to g
inclusiveBetween("a", "g", "z");
Validate exclusiveBetween
The exclusiveBetween accepts two values and an argument and checks if the argument value falls between the range formed by the two (exclusive) values passed. Note that the passed values are exclusive and hence the range’s edge values don’t count.
// java.lang.IllegalArgumentException: The value 1 is not in the specified exclusive range of 1 to 3
exclusiveBetween(1L, 3L, 1L);
Validate isInstanceOf
The isInstanceOf method validates that the passed argument is an instance of a specified class (throws an exception if it is not).
isInstanceOf(String.class, "abcd"); // no exceptions are thrown
// java.lang.IllegalArgumentException: Expected type: java.lang.String, actual: java.lang.Integer
isInstanceOf(String.class, 123);
// java.lang.IllegalArgumentException: Invalid cast
isInstanceOf(String.class,123, "Invalid cast");
Validate isAssignableFrom
The isAssignableFrom method checks if the passed argument type can be converted to the specified class (throwing an exception if it cannot be).
Validate.isAssignableFrom(CharSequence.class, String.class);
// java.lang.IllegalArgumentException: Cannot assign a java.lang.CharSequence to a java.lang.String
Validate.isAssignableFrom(String.class, CharSequence.class);
In the first call, no exceptions are thrown as a String is a CharSequence, but the reverse is not true and hence the second call failed.
Conclusion
This concludes the post on the Apache Commons Lang Validate class utility methods to validate the arguments. Check out the other posts on the Apache Commons Library.