Spring Null-Safety Аннотации

Spring Null-Safety Аннотации

1. обзор

Начиная с Spring 5, теперь у нас есть доступ к интересной функции, помогающей нам писать более безопасный код. Эта функция называется null-safety, группой аннотаций, работающих как защита, которая следит за потенциальными нулевыми ссылками.

Вместо того, чтобы позволить нам уйти от небезопасного кода,the null-safety feature produces warnings at compile time. Такие предупреждения могут предотвратить катастрофические исключения нулевого указателя (NPE) во время выполнения.

2. Аннотация@NonNull

Аннотация@NonNull является наиболее важной среди всех аннотаций функции нулевой безопасности. We can use this annotation t0 declare non-null constraint anywhere an object reference is expected: поле, параметр метода или возвращаемое значение метода.

Предположим, у нас есть класс с именемPerson:

public class Person {
    private String fullName;

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

    // getter
}

Это определение класса допустимо, но имеет дефект - в полеfullName может быть установлено значениеnull. Если это произойдет, мы можем получить NPE при работе сfullName.

Функция нулевой безопасности Spring позволяет инструментам сообщать о такой опасности. Например, если мы напишем код в IntelliJ IDEA и украсим полеfullName аннотацией@NonNull, мы увидим предупреждение:

image

Благодаря этой индикации мы заранее знаем о проблеме и можем предпринять соответствующие действия, чтобы избежать сбоя во время выполнения.

3. Аннотация@NonNullFields

Аннотация@NonNull помогает гарантировать нулевую безопасность. Однако мы бы загрязнили всю кодовую базу, если бы украсили все ненулевые поля этой аннотацией.

Мы можем избежать злоупотребления@NonNull с помощью другой аннотации -@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.

Чтобы аннотация@NonNullFields заработала, нам нужно создать файл с именемpackage-info.java в корневом каталоге пакета и аннотировать пакет с помощью@NonNullFields:

@NonNullFields
package org.example.nullibility;

Давайте объявим еще одно свойство в классеPerson под названиемnickName:

package org.example.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
}

На этот раз мы не украшаем полеnickName символом@NonNull, но все же видим аналогичную оговорку:

image

Аннотация@NonNullFields делает наш код менее подробным, обеспечивая при этом тот же уровень безопасности, что и@NonNull.

4. Аннотация@Nullable

Аннотация@NonNullFields обычно предпочтительнее, чем@NonNull, поскольку она помогает уменьшить шаблонность. Иногда мы хотим освободить некоторые поля от ненулевого ограничения, заданного на уровне пакета.

Вернемся к полюnickName и украсим его аннотацией@Nullable:

@Nullable
private String nickName;

Предупреждение, которое мы видели раньше, исчезло:

image

В этой ситуацииwe used the @Nullable annotation to override the semantics of @NonNullFields on a field.

5. Аннотация@NonNullApi

Аннотация@NonNullFields применяется только к, как следует из названия, полям. If we want to have the same impact on the methods' parameters and return values, we’ll need @NonNullApi.

Как и в случае с@NonNullFields, мы должны указать аннотацию@NonNullApi в файлеpackage-info.java:

@NonNullApi
package org.example.nullibility;

Давайте определим геттер для поляnickName:

package org.example.nullibility;

// import statements

public class Person {
    @Nullable
    private String nickName;

    String getNickName() {
        return nickName;
    }

    // other declarations
}

При действующей аннотации@NonNullApi выдается предупреждение о возможном значенииnull, созданном методомgetNickName:

image

Обратите внимание, что так же, как аннотация@NonNullFields, мы можем переопределить@NonNullApi на уровне метода с помощью аннотации@Nullable.

6. Заключение

Spring null-safety - отличная функция, которая помогает уменьшить вероятность появления NPE. Тем не менее, при использовании этой функции необходимо учитывать два важных момента:

  • Его можно использовать только в вспомогательном средстве разработки, таком как IntelliJ IDEA.

  • Он не применяет проверкиnull во время выполнения - нам все равно нужно писать код самостоятельно, чтобы предотвратить NPE

Исходный код этого руководства можно найти вover on GitHub.