Guava Preconditions for Input Validation: Complete Guide to checkArgument and Validation Utilities
Guava's Preconditions class provides static methods like checkArgument, checkState, and checkNotNull to validate method arguments and object state, throwing standard unchecked exceptions only when conditions fail.
The Google Guava library includes a comprehensive input validation framework centered in com.google.common.base.Preconditions. This utility class standardizes Guava preconditions for input validation across Java projects, offering lazy-formatted error messages and type-specific overloads that minimize performance overhead. Located at guava/src/com/google/common/base/Preconditions.java, these static methods serve as the foundation for defensive programming in Guava and downstream applications.
Core Validation Methods
The Preconditions class organizes validation into six primary method families, each targeting specific validation scenarios and throwing distinct exception types.
checkArgument for Method Parameters
Use checkArgument to validate method arguments supplied by external callers. When the boolean expression evaluates to false, the method throws IllegalArgumentException.
The implementation performs a simple boolean check:
public static void checkArgument(boolean expression) {
if (!expression) {
throw new IllegalArgumentException();
}
}
For formatted error messages, the var-args overload uses lazy formatting via Platform.lenientFormat to avoid string concatenation overhead in the success path:
public static void checkArgument(
boolean expression,
String errorMessageTemplate,
@Nullable Object @Nullable ... errorMessageArgs) {
if (!expression) {
throw new IllegalArgumentException(
Platform.lenientFormat(errorMessageTemplate, errorMessageArgs));
}
}
checkState for Internal Object State
Use checkState to verify an object's internal state before proceeding with operations. This method throws IllegalStateException when the condition fails, distinguishing state errors from argument errors.
public static void checkState(
boolean expression,
@Nullable String errorMessageTemplate,
@Nullable Object @Nullable ... errorMessageArgs) {
if (!expression) {
throw new IllegalStateException(
Platform.lenientFormat(errorMessageTemplate, errorMessageArgs));
}
}
checkNotNull for Null Safety
The checkNotNull method ensures a reference is non-null, typically for required constructor or method parameters. Unlike standard null checks, this method returns the validated reference, enabling inline assignment.
public static <T> T checkNotNull(@Nullable T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}
Index Validation Methods
For collection and array manipulation, Guava provides three index-checking methods that throw IndexOutOfBoundsException or IllegalArgumentException:
checkElementIndex: Validates an index is within[0, size)checkPositionIndex: Validates a position is within[0, size]checkPositionIndexes: Validates a range[start, end)fits within a container
The checkElementIndex implementation validates bounds and generates descriptive error messages:
public static int checkElementIndex(int index, int size, String desc) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
}
return index;
}
For range validation, checkPositionIndexes ensures sub-list operations remain within bounds:
public static void checkPositionIndexes(int start, int end, int size) {
// implementation omitted for brevity – throws IndexOutOfBoundsException
}
Architectural Features and Performance
The Preconditions implementation in guava/src/com/google/common/base/Preconditions.java emphasizes performance-aware validation through several key design decisions:
- Lazy message formatting: Error message templates using
%splaceholders are only formatted when a check fails, avoiding unnecessary string processing in the success path viaPlatform.lenientFormat(located inguava/src/com/google/common/base/Platform.java). - Primitive overloads: Separate methods for
char,int, andlongparameters prevent autoboxing overhead and var-args array allocation in common cases. - No checked exceptions: All validation failures throw unchecked exceptions, keeping client code clean without mandatory try-catch blocks.
- GWT compatibility: The class carries the
@GwtCompatibleannotation, enabling use in Google Web Toolkit projects. - Null-safety alternatives: While
checkNotNullremains available, Guava recommends usingObjects.requireNonNullfor simple non-precondition null checks, withVerify.verifyNotNullavailable inguava/src/com/google/common/base/Verify.javafor non-precondition assertions.
Practical Code Examples
The following patterns demonstrate idiomatic usage of Guava preconditions in service classes:
import com.google.common.base.Preconditions;
public class UserService {
/** Validates that the supplied age is non‑negative. */
public void setAge(int age) {
Preconditions.checkArgument(age >= 0, "Age (%s) must be non‑negative", age);
this.age = age;
}
/** Checks that the internal cache has been initialized before use. */
public void clearCache() {
Preconditions.checkState(cache != null, "Cache must be initialized before clearing");
cache.clear();
}
/** Ensures a non‑null configuration object is passed to the constructor. */
public UserService(Config config) {
this.config = Preconditions.checkNotNull(config,
"Configuration object must not be null");
}
/** Validates an index into a list of users. */
public User getUser(int index, List<User> users) {
Preconditions.checkElementIndex(index, users.size(),
"User index");
return users.get(index);
}
/** Validates a sub‑list range. */
public List<User> subList(List<User> users, int from, int to) {
Preconditions.checkPositionIndexes(from, to, users.size());
return users.subList(from, to);
}
}
Summary
checkArgumentvalidates method arguments and throwsIllegalArgumentExceptionfor invalid inputs supplied by callers.checkStateverifies object state and throwsIllegalStateExceptionwhen internal conditions are violated before operations proceed.checkNotNullensures non-null references, throwingNullPointerExceptionand returning the validated object for inline assignment.- Index methods (
checkElementIndex,checkPositionIndex,checkPositionIndexes) validate array and collection bounds, throwingIndexOutOfBoundsExceptionfor invalid indices or ranges. - All methods support lazy message formatting with
%splaceholders to avoid performance penalties on successful validation. - The
Preconditionsclass is annotated with@GwtCompatibleand resides inguava/src/com/google/common/base/Preconditions.java.
Frequently Asked Questions
What is the difference between checkArgument and checkState?
checkArgument validates inputs provided by callers to a method, throwing IllegalArgumentException when parameters violate constraints. checkState validates the internal state of an object before performing operations, throwing IllegalStateException when the object is not in the correct condition to proceed. Use checkArgument for public API validation and checkState for invariant checking within your class implementation.
How does lazy message formatting work in Guava Preconditions?
Guava's var-args overloads accept error message templates with %s placeholders but defer string formatting until a check actually fails. According to the source code in Preconditions.java, successful validations avoid the overhead of Platform.lenientFormat entirely, while failures format the message only when constructing the exception. This design eliminates unnecessary string concatenation costs in the common success path.
Should I use Preconditions.checkNotNull or Objects.requireNonNull?
While Preconditions.checkNotNull returns the validated reference and supports custom error messages via lazy formatting, Guava recommends using Java's standard Objects.requireNonNull for simple null checks that don't require precondition semantics. Use checkNotNull when you need formatted error messages or when maintaining consistency with other Guava precondition checks in your validation logic.
Which exception types do the index validation methods throw?
The checkElementIndex, checkPositionIndex, and checkPositionIndexes methods throw IndexOutOfBoundsException when indices or ranges fall outside valid bounds. In certain edge cases involving invalid size parameters, they may also throw IllegalArgumentException. These methods are designed for validating access to arrays, lists, and other indexed collections.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →