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, мы увидим предупреждение:
Благодаря этой индикации мы заранее знаем о проблеме и можем предпринять соответствующие действия, чтобы избежать сбоя во время выполнения.
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, но все же видим аналогичную оговорку:
Аннотация@NonNullFields делает наш код менее подробным, обеспечивая при этом тот же уровень безопасности, что и@NonNull.
4. Аннотация@Nullable
Аннотация@NonNullFields обычно предпочтительнее, чем@NonNull, поскольку она помогает уменьшить шаблонность. Иногда мы хотим освободить некоторые поля от ненулевого ограничения, заданного на уровне пакета.
Вернемся к полюnickName и украсим его аннотацией@Nullable:
@Nullable
private String nickName;
Предупреждение, которое мы видели раньше, исчезло:
В этой ситуации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:
Обратите внимание, что так же, как аннотация@NonNullFields, мы можем переопределить@NonNullApi на уровне метода с помощью аннотации@Nullable.
6. Заключение
Spring null-safety - отличная функция, которая помогает уменьшить вероятность появления NPE. Тем не менее, при использовании этой функции необходимо учитывать два важных момента:
-
Его можно использовать только в вспомогательном средстве разработки, таком как IntelliJ IDEA.
-
Он не применяет проверкиnull во время выполнения - нам все равно нужно писать код самостоятельно, чтобы предотвратить NPE
Исходный код этого руководства можно найти вover on GitHub.