skip to content

What is Objects.requireNonNull and when should you use it for fail-fast null checks?

level: juniorimportance: must knowfreq 72%

answer

  1. Throws NPE now if null, else returns the value
  2. Validate-and-assign in one line in constructors
  3. Message overload names the offending parameter
  4. Supplier overload = lazy message, only built on null
  5. Fail fast at the boundary, not deep in the code

basics

~20 s

Objects.requireNonNull(x) throws a NullPointerException immediately if x is null, otherwise returns x. You use it to validate arguments early - usually in constructors - so a bad null fails right away with a clear message instead of later somewhere confusing.

solid answer

~40 s

Objects.requireNonNull validates that a reference isn't null and, if it is, throws NullPointerException right there - 'fail fast'. There are two main overloads: requireNonNull(T obj) and requireNonNull(T obj, String message), where the message describes what was null (usually the parameter name) so the stack trace is actionable. It returns the value when non-null, which lets you assign and check in one line: this.repo = Objects.requireNonNull(repo, "repo");. The point is to surface programming errors at the boundary - the constructor or method entry - rather than letting null travel deep into the system and blow up far from the cause. A third overload takes a Supplier<String> to build the message lazily, useful when the message is expensive to construct. Use it to enforce non-null invariants on parameters and required dependencies.

code

java · 19 lines
java
import java.util.Objects;

public final class Greeting {
    private final String name;

    public Greeting(String name) {
        // Fail fast at the boundary with a named message.
        this.name = Objects.requireNonNull(name, "name must not be null");
    }

    void demo() {
        new Greeting("Ada");          // ok, returns and assigns "Ada"
        // new Greeting(null);        // -> NullPointerException: name must not be null

        // Lazy message: only built if the value is null
        String cfg = System.getProperty("cfg");
        Objects.requireNonNull(cfg, () -> "missing cfg at " + System.nanoTime());
    }
}

go deeper

for a junior

Knows requireNonNull throws NPE on null and is used to validate constructor arguments.

for a middle

Uses the message overload and the validate-and-assign idiom; distinguishes it from Optional and assert.

for a senior

Knows the Supplier lazy-message overload, when to fail fast vs. handle expected absence, and the assertions-disabled caveat.

for a principal

Sets null-handling conventions (boundary validation, @NonNull annotations, helpful NPE interplay) and reasons about API contracts and defensive vs. trusting layers.

## The idea: fail fast 'Fail fast' means: when something is wrong (a null where you require a value), detect it **immediately at the boundary** and throw, instead of storing the bad value and crashing much later in some unrelated method. A late crash gives a stack trace pointing at the symptom, not the cause; an early crash points right at the mistake. ## What requireNonNull does `Objects.requireNonNull` (Java 7+) is a static helper with these key overloads: ```java static <T> T requireNonNull(T obj) // throws NPE if null static <T> T requireNonNull(T obj, String message) // NPE with that message static <T> T requireNonNull(T obj, Supplier<String> msgSupplier) // Java 8+, lazy message ``` Behaviour: - If `obj` is **null**, it throws `NullPointerException` (with your message, if given). - If `obj` is **non-null**, it **returns `obj`** unchanged. Because it returns the value, you can validate and assign in one expression - the idiomatic constructor pattern. ## The canonical use: constructor parameter validation ```java public final class OrderService { private final Repo repo; private final Clock clock; public OrderService(Repo repo, Clock clock) { this.repo = Objects.requireNonNull(repo, "repo"); this.clock = Objects.requireNonNull(clock, "clock"); } } ``` If a caller passes `null` for `repo`, construction fails instantly with `NullPointerException: repo` - you know exactly which dependency was missing. Without the check, `repo` would be stored as null and the first method that calls `repo.find(...)` would throw an NPE with no hint about who passed the null or where. ## Why the message overload matters A bare `NullPointerException` tells you very little - especially across many fields. `requireNonNull(x, "customerId")` produces `NullPointerException: customerId`, naming the offending parameter. **Always prefer the message overload** for non-trivial classes. Convention: the message is the parameter name (or a short description). ## The Supplier overload (lazy message) `requireNonNull(obj, () -> "expensive: " + buildContext())` builds the message **only if** the value is actually null. Use it when constructing the message is costly (string concatenation, lookups) and you don't want to pay that cost on the common, non-null path. ## Contrast with assertions and Optional - **`assert x != null`** can be disabled at runtime (assertions are off unless `-ea` is set), so it's unsuitable for enforcing real invariants on public APIs. `requireNonNull` always runs. - **`Optional`** is for *return values* that may legitimately be absent - not for parameter validation. Don't take `Optional` parameters just to express 'may be null'; validate with `requireNonNull` instead. ## What it is NOT for It's for **programming errors** (a contract says non-null, caller broke it) - not for ordinary, expected absence like 'user typed nothing'. For expected-empty input, handle it with normal control flow or a default (see `requireNonNullElse`), don't throw. ## Modern note From Java 14+, the JVM's 'Helpful NullPointerExceptions' improve messages for plain NPEs, but explicit `requireNonNull` at the boundary is still best practice: it documents the invariant, fails at the right place, and lets you give a precise message.

  • Why prefer Objects.requireNonNull over an 'assert x != null' statement for a public constructor?
    Assertions are disabled at runtime unless the JVM is started with -ea, so they can't be relied on to enforce invariants. requireNonNull always executes and always throws, making it safe for public-API contract enforcement.
  • When would you use the Supplier<String> overload?
    When building the error message is expensive (concatenation, lookups, formatting). The supplier is only invoked if the value is actually null, so you avoid that cost on the normal non-null path.

saying these in an interview costs you the question

  • Using assert for invariants (disabled without -ea) instead of requireNonNull
  • Using requireNonNull for expected-empty user input (use requireNonNullElse/control flow)
  • Forgetting it returns the value, so writing a separate if-throw
  • Taking Optional parameters instead of requireNonNull-ing nullable ones

context