«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.