Objects.requireNonNullElse()

Swap a null for a default value in one call, with requireNonNullElseGet when the default is costly to create.

Signature
public static <T> T requireNonNullElse(T obj, T defaultObj)
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
  • Added in Java Java 9

Parameters

ParameterTypeDescription
$objTThe value to use if it is not null.
$defaultObjTThe fallback for requireNonNullElse. Evaluated before the call, and must not be null.
$supplieroptionalSupplier<? extends T>For requireNonNullElseGet: called only when obj is null, and must return a non-null value.

Return value

Tobj if it is not null; otherwise defaultObj (or the supplier's result), which must itself be non-null.

Errors

NullPointerException if obj and defaultObj are both null, or, for requireNonNullElseGet, if obj is null and the supplier is null or returns null.

Java has no ?? operator. Objects.requireNonNullElse(value, fallback) is the closest thing in the JDK: it returns value if it is not null and fallback otherwise. The name sounds like a check, but its job is defaulting; the "require" part is that the result is guaranteed non-null.

When to use it

Any time a nullable value from outside needs a sensible default: an optional query parameter, a JSON field the client left out, a nullable column, a configuration entry. It reads better than a ternary and does not evaluate the value expression twice.

int pageSize = Integer.parseInt(
        Objects.requireNonNullElse(params.get("size"), "20"));
List<String> tags = Objects.requireNonNullElse(body.tags(), List.of());

Else versus ElseGet

Arguments in Java are evaluated before the call, so requireNonNullElse(cached, loadFromDatabase()) runs the query every time, even when cached is present. requireNonNullElseGet(cached, () -> loadFromDatabase()) only calls the supplier when it is needed. Constants and literals belong in the first form; anything that allocates, queries or computes belongs in the second.

Mistakes people make

  • Passing a default that can itself be null. If both are null the method throws NullPointerException. If null is an acceptable result, use a plain ternary instead.
  • Expecting it to treat empty strings as missing. requireNonNullElse("", "20") returns "". A query string like ?size= gives an empty value, not null, so handle blanks separately.
  • Wrapping in Optional just to default a value. Optional.ofNullable(x).orElse(d) works, but allocates and says more than you mean. Keep Optional for return types and use this for plain defaulting.

Back-end angle

Normalising request DTOs is the main use. Replacing null collections with empty ones early means the rest of the service can loop and stream without null checks, and replacing missing paging values with defaults keeps queries bounded. For Map lookups, getOrDefault does the same job when the key is absent.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Filling in default page number and page size when a list endpoint is called without paging parameters.
  • Replacing a null list in an incoming JSON body with an empty list so later code can loop without null checks.
  • Using a configured value if present and an expensive computed default, via requireNonNullElseGet, only when it is missing.

Frequently asked questions

Does Java have a null coalescing operator like ?? in C# or JavaScript?

No. Objects.requireNonNullElse(a, b) is the JDK method that does the same job, and requireNonNullElseGet defers building the default.

What is the difference between requireNonNullElse and Optional.orElse?

They return the same thing when the default is non-null. requireNonNullElse works on a plain value without creating an Optional and throws if the default is null, while Optional.orElse accepts a null default.

Why does requireNonNullElse throw a NullPointerException?

Because both the value and the default were null. The method promises a non-null result, so it rejects a null default.

More examples

Else evaluates the default, ElseGet does not

The first call loads the default even though a saved value exists. With requireNonNullElseGet the supplier only runs when the value is actually null.

Example · java
int loads = 0;

String loadDefaultTheme() {
    loads++;
    return "light";
}

void main() {
    String saved = "dark";

    String a = Objects.requireNonNullElse(saved, loadDefaultTheme());
    IO.println(a + ", loads=" + loads);

    String b = Objects.requireNonNullElseGet(saved, this::loadDefaultTheme);
    IO.println(b + ", loads=" + loads);

    String c = Objects.requireNonNullElseGet(null, this::loadDefaultTheme);
    IO.println(c + ", loads=" + loads);
}
// Output:
// dark, loads=1
// dark, loads=1
// light, loads=2

Empty strings are not null

A missing parameter is null and gets the default, but ?size= arrives as an empty string and passes straight through. The blank check covers that second case.

Example · java
int pageSize(Map<String, String> query) {
    String raw = Objects.requireNonNullElse(query.get("size"), "20");
    return raw.isBlank() ? 20 : Integer.parseInt(raw.strip());
}

void main() {
    IO.println(pageSize(Map.of("size", "50")));
    IO.println(pageSize(Map.of()));
    IO.println(pageSize(Map.of("size", "")));
}
// Output:
// 50
// 20
// 20

Both null throws

The method guarantees a non-null result, so a null default is rejected. When null is a valid outcome, a plain ternary is the honest choice.

Example · java
void main() {
    String configured = null;
    String fallback = null;
    try {
        Objects.requireNonNullElse(configured, fallback);
    } catch (NullPointerException e) {
        IO.println("NullPointerException: " + e.getMessage());
    }
    String region = configured != null ? configured : fallback;
    IO.println(region);
}
// Output:
// NullPointerException: defaultObj
// null

Discussion

  • Be the first to comment on this lesson.