Partner – Microsoft – NPI (cat= Spring)
announcement - icon

Azure Spring Apps is a fully managed service from Microsoft (built in collaboration with VMware), focused on building and deploying Spring Boot applications on Azure Cloud without worrying about Kubernetes.

And, the Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

>> Learn more and deploy your first Spring Boot app to Azure.

You can also ask questions and leave feedback on the Azure Spring Apps GitHub page.

1. Overview

Starting with Spring 5, we now have access to an interesting feature helping us write safer code. This feature is called null safety, a group of annotations working like a safeguard that watches out for potential null references.

Rather than letting us get away with unsafe code, the null-safety feature produces warnings at compile time. Such warnings may prevent catastrophic null pointer exceptions (NPEs) at runtime.

2. The @NonNull Annotation

The @NonNull annotation is the most important among all the annotations of the null-safety feature. We can use this annotation to declare non-null constraint anywhere an object reference is expected: a field, a method parameter or a method’s return value.

Suppose we have a class named Person:

public class Person {
    private String fullName;

    void setFullName(String fullName) {
        if (fullName != null && fullName.isEmpty()) {
            fullName = null;
        }
        this.fullName = fullName;
    }

    // getter
}

This class definition is valid but has a defect – the fullName field may be set to null. If this happens, we could end up with an NPE when working with fullName.

The Spring null-safety feature enables tools to report such a danger. For instance, if we write code in IntelliJ IDEA and decorate the fullName field with the @NonNull annotation, we’ll see a warning:

nonnul annotation

Thanks to this indication, we’re aware of the problem in advance and able to take appropriate action to avoid a runtime failure.

3. The @NonNullFields Annotation

The @NonNull annotation is helpful in guaranteeing null safety. However, we would pollute the whole code base if adorning all non-null fields with this annotation.

We can avoid the abuse of @NonNull with another annotation – @NonNullFields. This annotation is applicable at the package level, notifying our development tools that all fields in the annotated package are, by default, non-null.

For the @NonNullFields annotation to kick in, we need to create a file named package-info.java in the root directory of the package and annotate the package with @NonNullFields:

@NonNullFields
package org.baeldung.nullibility;

Let’s declare another property in the Person class called nickName:

package org.baeldung.nullibility;

// import statements

public class Person {
    private String nickName;

    void setNickName(@Nullable String nickName) {
        if (nickName != null && nickName.isEmpty()) {
            nickName = null;
        }
        this.nickName = nickName;
    }

    // other declarations
}

This time, we don’t embellish the nickName field with @NonNull but still see a similar caveat:

nonnullfields annotation 3

The @NonNullFields annotation makes our code less verbose while ensuring the same level of safety that @NonNull provides.

4. The @Nullable Annotation

The @NonNullFields annotation is generally preferable to @NonNull as it helps reduce boilerplate. At times we want to exempt some fields from the non-null constraint specified at the package level.

Let’s go back to the nickName field and decorate it with the @Nullable annotation:

@Nullable
private String nickName;

The warning we saw before is gone now:

nullable annotation

In this situation, we used the @Nullable annotation to override the semantics of @NonNullFields on a field.

5. The @NonNullApi Annotation

The @NonNullFields annotation only applies to, as its name suggests, fields. If we want to have the same impact on the methods’ parameters and return values, we’ll need @NonNullApi.

As with @NonNullFields, we must specify the @NonNullApi annotation in the package-info.java file:

@NonNullApi
package org.baeldung.nullibility;

Let’s define a getter for the nickName field:

package org.baeldung.nullibility;

// import statements

public class Person {
    @Nullable
    private String nickName;

    String getNickName() {
        return nickName;
    }

    // other declarations
}

With the @NonNullApi annotation in effect, a warning is issued about a possibly null value produced by the getNickName method:

nonnullapi annotation

Notice that just like the @NonNullFields annotation, we can override the @NonNullApi at the method level with the @Nullable annotation.

6. Conclusion

Spring null safety is a great feature that helps diminish the possibility of NPEs. However, there are two important points we need to beware of while using this feature:

  • It’s only usable in a supporting development tool, such as IntelliJ IDEA
  • It doesn’t enforce null checks at runtime – we still need to write code ourselves to avert NPEs

The source code for this tutorial can be found on GitHub.

Course – LS (cat=Spring)

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

>> THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.