eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Introduction

A NullPointerException is one of Java’s most common exceptions. It occurs when accessing or interacting with a reference variable that points to null. Validating objects, especially when they’re parameters in methods or constructors, is important to ensure robust and reliable code. We can do this by writing our null-checking code, using third-party libraries, or choosing a more convenient approach.

In this tutorial, we’ll look at the latter – a flexible, built-in solution Java offers with the Objects.requireNonNull() methods.

2. Null Value Handling

To briefly review, many alternatives are available to avoid manual null checks. Instead of wrapping our code with if statements, which could be error-prone and time-consuming, we can choose from various libraries. Spring, Lombok (@NonNull), and Uber’s NullAway are just a few of them.

In contrast, if we want to maintain consistency, avoid introducing additional libraries to our code base, or use vanilla Java, we can choose between Optional class or Objects methods. While Optional simplifies null values handling, it often adds coding overhead and clutters the code for simple use cases. Since it’s a separate object, it also consumes extra memory. Moreover, Optional only transforms a NullPointerException into a NoSuchElementException, i.e., it doesn’t resolve the defect.

On the other hand, the Objects class provides static utility methods for working with objects more efficiently. Introduced in Java 7 and updated several times across Java 8 and 9, it also provides methods to validate conditions before performing operations.

3. Advantages of Objects.requireNonNull()

The Objects class simplifies checking and handling null values by providing a set of requireNonNull() static methods. These methods offer a straightforward and concise approach to checking for null objects before use.

The primary purpose of the requireNonNull() methods is to check if an object reference is null and throw a NullPointerException if it is. By explicitly throwing the exception, we communicate the intent of the check, making the code easier to understand and maintain. This also informs developers and maintainers that the error is deliberate, which helps prevent unintentional changes to the behavior over time.

The Objects class is part of the java.util package, which makes it easily accessible without requiring external libraries or dependencies. Its methods are well-documented, providing developers with clear instructions for correct usage.

4. Use Cases and Overloaded Methods

Let’s now focus on various use cases and overloaded variants of the requireNonNull() method.

These methods allow handling null values in different scenarios, from simple null checks to more complex validations with custom messages.

Additionally, two other methods support default values – requireNonNullElse() and requireNonNullElseGet(). By understanding these use cases, we can effectively incorporate requireNonNull() into our code base.

4.1. Single Parameter Validation in Methods and Constructors

First, let’s look at the implementation of the simplest one – requireNonNull() with a single parameter:

public static <T> T requireNonNull(T obj) {
    if (obj == null) {
        throw new NullPointerException();
    } else {
        return obj;
    }
}

The method checks if the provided object reference is null. If it is, it throws a NullPointerException. Otherwise, the unchanged object is returned.

This method is primarily used for parameter validation in methods and constructors. For instance, to make sure the name passed to the greet() method isn’t null, we can use the following approach:

void greet(String name) {
    Objects.requireNonNull(name, "Name cannot be null");
    logger.info("Hello, {}!", name);
}

@Test
void givenObject_whenGreet_thenNoException() {
    Assertions.assertDoesNotThrow(() -> greet("Baeldung"));
}

@Test
void givenNull_whenGreet_thenException() {
    Assertions.assertThrows(NullPointerException.class, () -> greet(null));
}

By using requireNonNull(), we can ensure methods receive valid arguments. We can detect null objects before we use them, preventing errors when those objects are accessed.

4.2. Multiple Parameter Validation With Custom Error Messages

Next, let’s check how to handle scenarios where our methods or constructors receive multiple arguments. A variant of Objects.requireNonNull() accepts a String message beside the object reference checked for nullity. This enables throwing a NullPointerException with a custom error message in case the object reference is null:

public static <T> T requireNonNull(T obj, String message) {
    if (obj == null)
        throw new NullPointerException(message);
    return obj;
}

We can use this method for validation in constructors with multiple parameters:

static class User {
    private final String username;
    private final String password;

    public User(String username, String password) {
        this.username = Objects.requireNonNull(username, "Username is null!");
        this.password = Objects.requireNonNull(password, "Password is null!");
    }

    // getters
}

@Test
void givenValidInput_whenNewUser_thenNoException() {
    Assertions.assertDoesNotThrow(() -> new User("Baeldung", "Secret"));
}

@Test
void givenNull_whenNewUser_thenException() {
    Assertions.assertThrows(NullPointerException.class, () -> new User(null, "Secret"));
    Assertions.assertThrows(NullPointerException.class, () -> new User("Baeldung", null));
}

NullPointerExceptions with custom messages provide more context by specifying what went wrong and which parameter caused the issue. This, in turn, improves error reporting and makes debugging easier.

4.3. Deferring Message Creation With Supplier

Finally, we can customize a NullPointerException with another overloaded method:

public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
    if (obj == null) {
        throw new NullPointerException(messageSupplier == null ? null : (String)messageSupplier.get());
    } else {
        return obj;
    }
}

The second parameter is a Supplier for the error message. It allows deferred message creation until after the null check, which could improve the performance. This is particularly valuable in costly operations, such as string concatenation or complex calculations:

void processOrder(UUID orderId) {
    Objects.requireNonNull(orderId, () -> {
        String message = "Order ID cannot be null! Current timestamp: " + getProcessTimestamp();
        message = message.concat("Total number of invalid orders: " + getOrderAmount());
        message = message.concat("Please provide a valid order.");
        return message;
    });
    logger.info("Processing order with id: {}", orderId);
}

private static int getOrderAmount() {
    return new Random().nextInt(100_000);
}

private static Instant getProcessTimestamp() {
    return Instant.now();
}

@Test
void givenObject_whenProcessOrder_thenNoException() {
    Assertions.assertDoesNotThrow(() -> processOrder(UUID.randomUUID()));
}

@Test
void givenNull_whenProcessOrder_thenException() {
    Assertions.assertThrows(NullPointerException.class, () -> processOrder(null));
}

In the example above, getOrderAmount() and getProcessTimestamp() could involve time-consuming operations, such as database queries or external API calls. By deferring the message creation, this approach prevents unnecessary performance costs when the orderId isn’t null.

Nevertheless, it’s important to ensure that the overhead of creating the message Supplier is lower than directly generating the String message.

5. Best Practices

As we’ve seen earlier, when designing methods and constructors, we need to enforce parameter restrictions to ensure our code’s predictable behavior. Using Objects.requireNonNull() at the start of a method or constructor helps catch invalid arguments early. This practice also keeps our code clean, easier to maintain, and simpler to debug.

What’s more, requireNonNull() can be essential in building a fail-fast system. The fail-fast principle implies errors are detected immediately, preventing cascading failures and reducing debugging complexity. If a method validates its parameters upfront, it fails quickly with a clear exception, making the source of the issue apparent. These checks are necessary for the system to avoid producing confusing errors, incorrect results, or even problems in unrelated parts of the code.

Another good practice is explicitly documenting the parameter restrictions for public or protected methods. We can use the Javadoc @throws tag to specify exceptions thrown if parameter restrictions are violated. If multiple methods throw a NullPointerException, we can cover this in the class-level Javadoc instead of repeating it for each method.

6. Conclusion

In this tutorial, we demonstrated how to efficiently validate method and constructor parameters using Objects.requireNonNull() and its overloaded variations. These methods provide a simple yet powerful way to handle null checks in Java. A built-in support for custom error messages and deferred message creation adds flexibility, making it suitable for various use cases.

Moreover, adopting best practices like enforcing parameter restrictions, using fail-fast principles, and documenting exceptions improves our codebase’s overall quality and maintainability.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)