«1. Обзор

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

Вместо того, чтобы позволить нам работать с небезопасным кодом, функция нулевой безопасности выдает предупреждения во время компиляции. Такие предупреждения могут предотвратить катастрофические исключения нулевого указателя (NPE) во время выполнения.

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

Аннотация @NonNull является наиболее важной среди всех аннотаций средства защиты от нулей. Мы можем использовать эту аннотацию, чтобы объявить ненулевое ограничение везде, где ожидается ссылка на объект: поле, параметр метода или возвращаемое значение метода.

Предположим, что у нас есть класс с именем 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, мы увидим предупреждение:

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

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

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

Мы можем избежать злоупотреблений @NonNull с помощью другой аннотации — @NonNullFields. Эта аннотация применима на уровне пакета, уведомляя наши средства разработки о том, что все поля в аннотированном пакете по умолчанию не пусты.

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

@NonNullFields
package org.baeldung.nullibility;

Давайте объявим еще одно свойство в класс Person, называемый 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
}

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

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

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

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

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

@Nullable
private String nickName;

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

В этой ситуации мы использовали аннотацию @Nullable для переопределения семантика @NonNullFields в поле.

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

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

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

@NonNullApi
package org.baeldung.nullibility;

Определим геттер для поля nickName:

package org.baeldung.nullibility;

// import statements

public class Person {
    @Nullable
    private String nickName;

    String getNickName() {
        return nickName;
    }

    // other declarations
}

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

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

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

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

    Ее можно использовать только в поддерживающем инструменте разработки, таком как IntelliJ IDEA. кодируем сами, чтобы предотвратить NPE

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