Objects.requireNonNull()
Fail fast with a clear NullPointerException when a required argument or dependency is null, at the point the mistake is made.
public static <T> T requireNonNull(T obj)
public static <T> T requireNonNull(T obj, String message)
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier)- Added in Java Java 7
Parameters
| Parameter | Type | Description |
|---|---|---|
$obj | T | The value that must not be null. |
$messageoptional | String | Detail message for the exception, usually the parameter name. |
$messageSupplieroptional | Supplier<String> | Builds the detail message only if obj is null, useful when the message is costly to build. |
Return value
Tobj itself, unchanged, when it is not null.
Errors
NullPointerException if obj is null, with the given message (or the supplier's result) as its detail message.
Changelog
- PHP Java 8Added the overload that takes a Supplier<String> for the message.
Objects.requireNonNull(obj, "name") throws a NullPointerException if obj is null and otherwise returns it. It turns a null that would blow up later, somewhere unrelated, into an immediate failure that names the culprit.
Why fail fast
A null stored in a field does no harm until something uses it, possibly minutes later on another thread. The stack trace then points at the use, not at the code that passed the null in. Checking in the constructor or at the top of a public method moves the failure to the real cause. Because it returns its argument, the check fits inside an assignment:
OrderService(OrderRepository repository, Clock clock) {
this.repository = Objects.requireNonNull(repository, "repository");
this.clock = Objects.requireNonNull(clock, "clock");
}Choosing an overload
requireNonNull(obj)gives an exception with no message. Fine for internal code, poor in logs.requireNonNull(obj, "customerId")is the usual choice. A constant string costs nothing.requireNonNull(obj, () -> "no price for " + sku)builds the message only when it fails. Use it when the message needs string concatenation in a hot path.
Mistakes people make
- Using it to validate client input. A missing JSON field is the client's mistake and should become a 400 response with a clear error body, not a
NullPointerExceptionthat your error handler turns into a 500. KeeprequireNonNullfor programmer errors: wiring, contracts between your own classes, invariants. - Calling it and ignoring the result when you meant to assign it. Harmless, but it reads as if the value were used.
- Checking blank strings with it. It only checks null;
""and" "pass.
Back-end angle
Constructor injection plus requireNonNull makes a service impossible to create half-wired, which matters when classes are built by hand in tests or in a small service without a framework. In records, put the checks in the compact constructor so a DTO or value object can never exist with a missing required component.
Example
When to use it
- Checking injected dependencies in a service constructor so a half-wired object can never be created.
- Enforcing required components in a record's compact constructor for value objects and DTOs.
- Turning a missing configuration entry or lookup result into an immediate, clearly named failure at start-up.
Frequently asked questions
Should I use requireNonNull or throw IllegalArgumentException for null arguments?
The JDK convention is NullPointerException for a null that is not allowed, which is what requireNonNull throws. Use IllegalArgumentException for non-null values that are invalid, such as a negative quantity.
Why use requireNonNull if the code would throw NullPointerException anyway?
Because it throws earlier and with a message. Without it, a null stored in a field fails much later, where the stack trace no longer shows who passed it in.
Does requireNonNull check for empty strings?
No. It only checks for null. Use isBlank or isEmpty for strings, and proper validation for request input.
More examples
Required components in a record
The compact constructor runs for every instance, so no Money can exist without a currency. The message names the missing component.
record Money(String currency, long minorUnits) {
Money {
Objects.requireNonNull(currency, "currency");
}
}
void main() {
IO.println(new Money("GBP", 1999));
try {
new Money(null, 500);
} catch (NullPointerException e) {
IO.println("rejected: " + e.getMessage());
}
}
// Output:
// Money[currency=GBP, minorUnits=1999]
// rejected: currencyBuilding the message lazily with a Supplier
The lambda only runs when the price is missing, so the happy path never pays for the string concatenation. The returned value is used directly, unboxed to long.
final Map<String, Long> prices = Map.of("AB-1", 1250L);
long priceOf(String sku) {
return Objects.requireNonNull(prices.get(sku), () -> "no price configured for " + sku);
}
void main() {
IO.println(priceOf("AB-1"));
try {
priceOf("ZZ-9");
} catch (NullPointerException e) {
IO.println(e.getMessage());
}
}
// Output:
// 1250
// no price configured for ZZ-9Client input needs a 400, not an exception
Missing input from a client is expected and gets a proper error response. The last line shows that requireNonNull lets a blank string through, so it is no substitute for input validation.
record CreateUser(String email) {}
String handle(CreateUser body) {
if (body.email() == null || body.email().isBlank()) {
return "400 email is required";
}
return "201 created " + body.email();
}
void main() {
IO.println(handle(new CreateUser("[email protected]")));
IO.println(handle(new CreateUser(null)));
IO.println(handle(new CreateUser(" ")));
IO.println(Objects.requireNonNull(" ", "email").isBlank());
}
// Output:
// 201 created [email protected]
// 400 email is required
// 400 email is required
// true
Discussion