Quantcast
Channel: Baeldung
Viewing all articles
Browse latest Browse all 4535

Spring Null-Safety Annotations

$
0
0

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 t0 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:

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:

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 in and decorate it with the @Nullable annotation:

@Nullable
private String nickName;

The warning we saw before is gone now:

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 possible null value produced by the getNickName method:

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 over on GitHub.


Viewing all articles
Browse latest Browse all 4535

Trending Articles