Skip to content

Commit 0b14d67

Browse files
committed
Refine null-safety documentation terms
Closes gh-34982
1 parent 45ba4ac commit 0b14d67

File tree

1 file changed

+29
-30
lines changed

1 file changed

+29
-30
lines changed

framework-docs/modules/ROOT/pages/core/null-safety.adoc

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
[[null-safety]]
22
= Null-safety
33

4-
Although Java does not let you express null-safety with its type system, the Spring Framework codebase is annotated with
5-
https://jspecify.dev/docs/start-here/[JSpecify] annotations to declare the nullness of APIs, fields and related type
6-
usages. Reading the https://jspecify.dev/docs/user-guide/[JSpecify user guide] is highly recommended in order to get
7-
familiar with those annotations and semantics.
8-
9-
The primary goal of this explicit null-safety arrangement is to prevent `NullPointerException` to be thrown at runtime via
10-
build time checks and to turn explicit nullness into a way to express the possible absence of value. It is useful in
11-
both Java by leveraging some tooling (https://github.com/uber/NullAway[NullAway] or IDEs supporting null-safety
12-
annotations such as IntelliJ IDEA or Eclipse) and Kotlin where JSpecify annotations are automatically translated to
4+
Although Java does not let you express nullness markers with its type system yet, the Spring Framework codebase is
5+
annotated with https://jspecify.dev/docs/start-here/[JSpecify] annotations to declare the nullability of its APIs,
6+
fields and related type usages. Reading the https://jspecify.dev/docs/user-guide/[JSpecify user guide] is highly
7+
recommended in order to get familiar with those annotations and semantics.
8+
9+
The primary goal of this null-safety arrangement is to prevent `NullPointerException` to be thrown at runtime via build
10+
time checks and to turn explicit nullability into a way to express the possible absence of value. It is useful in both
11+
Java by leveraging some tooling (https://github.com/uber/NullAway[NullAway] or IDEs supporting JSpecify annotations
12+
such as IntelliJ IDEA for example) and Kotlin where JSpecify annotations are automatically translated to
1313
{kotlin-docs}/null-safety.html[Kotlin's null safety].
1414

1515
The {spring-framework-api}/core/Nullness.html[`Nullness` Spring API] can be used at runtime to detect the nullness of a
@@ -21,26 +21,26 @@ package).
2121
== Annotating libraries with JSpecify annotations
2222

2323
As of Spring Framework 7, the Spring Framework codebase leverages JSpecify annotations to expose null-safe APIs and
24-
to check the consistency of those null-safety declarations with https://github.com/uber/NullAway[NullAway] as part of
24+
to check the consistency of those nullability declarations with https://github.com/uber/NullAway[NullAway] as part of
2525
its build. It is recommended for each library depending on Spring Framework (Spring portfolio projects), as
2626
well as other libraries related to the Spring ecosystem (Reactor, Micrometer and Spring community projects), to do the
2727
same.
2828

2929
[[null-safety-applications]]
3030
== Leveraging JSpecify annotations in Spring applications
3131

32-
Developing applications with IDEs supporting null-safety annotations, such as IntelliJ IDEA or Eclipse, will provide
33-
warnings in Java and errors in Kotlin when the null-safety contracts are not honored, allowing Spring application
34-
developers to refine their null handling to prevent `NullPointerException` to be thrown at runtime.
32+
Developing applications with IDEs supporting nullness annotations will provide warnings in Java and errors in Kotlin
33+
when the nullability contracts are not honored, allowing Spring application developers to refine their null handling to
34+
prevent `NullPointerException` to be thrown at runtime.
3535

36-
Optionally, Spring application developers can annotate their codebase and use https://github.com/uber/NullAway[NullAway]
37-
to enforce null-safety during build time at application level.
36+
Optionally, Spring application developers can annotate their codebase and use build plugins like
37+
https://github.com/uber/NullAway[NullAway] to enforce null-safety during build time at application level.
3838

3939
[[null-safety-guidelines]]
4040
== Guidelines
4141

42-
The purpose of this section is to share some guidelines proposed for specifying explicitly the nullness of Spring-related
43-
libraries or applications.
42+
The purpose of this section is to share some guidelines proposed for specifying explicitly the nullability of
43+
Spring-related libraries or applications.
4444

4545

4646
[[null-safety-guidelines-jspecify]]
@@ -62,7 +62,7 @@ import org.jspecify.annotations.NullMarked;
6262

6363
In the various Java files belonging to the package, nullable type usages are defined explicitly with
6464
https://jspecify.dev/docs/api/org/jspecify/annotations/Nullable.html[`@Nullable`]. It is recommended that this
65-
annotation is specified just before the related type.
65+
annotation is specified just before the related type on the same line.
6666

6767
For example, for a field:
6868

@@ -81,9 +81,8 @@ public static @Nullable String buildMessage(@Nullable String message,
8181
}
8282
----
8383

84-
When overriding a method, nullness annotations are not inherited from the superclass method. That means those
85-
nullness annotations should be repeated if you just want to override the implementation and keep the same API
86-
nullness.
84+
When overriding a method, JSpecify annotations are not inherited from the superclass method. That means they should be
85+
repeated if you just want to override the implementation and keep the same nullability.
8786

8887
With arrays and varargs, you need to be able to differentiate the nullness of the elements from the nullness of
8988
the array itself. Pay attention to the syntax
@@ -111,10 +110,10 @@ typical use cases.
111110

112111
The recommended configuration is:
113112

114-
- `NullAway:OnlyNullMarked=true` in order to perform nullness checks only for packages annotated with `@NullMarked`.
113+
- `NullAway:OnlyNullMarked=true` in order to perform nullability checks only for packages annotated with `@NullMarked`.
115114
- `NullAway:CustomContractAnnotations=org.springframework.lang.Contract` which makes NullAway aware of the
116115
{spring-framework-api}/lang/Contract.html[@Contract] annotation in the `org.springframework.lang` package which
117-
can be used to express complementary semantics to avoid non-relevant null-safety warnings in your codebase.
116+
can be used to express complementary semantics to avoid non-relevant warnings in your codebase.
118117

119118
A good example of `@Contract` benefits is
120119
{spring-framework-api}/util/Assert.html#notNull(java.lang.Object,java.lang.String)[`Assert#notnull`] which is annotated
@@ -131,22 +130,22 @@ generates no warning with the recommended configuration mentioned above.
131130

132131
==== Warnings suppression
133132

134-
There are a few valid use cases where NullAway will wrongly detect nullness problems. In such case, it is recommended
133+
There are a few valid use cases where NullAway will wrongly detect nullability problems. In such case, it is recommended
135134
to suppress related warnings and to document the reason:
136135

137136
- `@SuppressWarnings("NullAway.Init")` at field, constructor or class level can be used to avoid unnecessary warnings
138137
due to the lazy initialization of fields, for example due to a class implementing
139138
{spring-framework-api}/beans/factory/InitializingBean.html[`InitializingBean`].
140139
- `@SuppressWarnings("NullAway") // Dataflow analysis limitation` can be used when NullAway dataflow analysis is not
141-
able to detect that the path involving a nullness problem will never happen.
140+
able to detect that the path involving a nullability problem will never happen.
142141
- `@SuppressWarnings("NullAway") // Lambda` can be used when NullAway does not take into account assertions performed
143142
outside of a lambda for the code path within the lambda.
144143
- `@SuppressWarnings("NullAway") // Reflection` can be used for some reflection operations that are known returning
145144
non-null values even if that can't be expressed by the API.
146145
- `@SuppressWarnings("NullAway") // Well-known map keys` can be used when `Map#get` invocations are done with keys known
147146
to be present and non-null related values inserted previously.
148-
- `@SuppressWarnings("NullAway") // Overridden method does not define nullness` can be used when the super class does
149-
not define nullness (typically when the super class is coming from a dependency).
147+
- `@SuppressWarnings("NullAway") // Overridden method does not define nullability` can be used when the super class does
148+
not define nullability (typically when the super class is coming from a dependency).
150149

151150

152151
[[null-safety-migrating]]
@@ -160,9 +159,9 @@ introduced in Spring Framework 5 when JSpecify did not exist and the best option
160159
but widespread JSR) meta-annotations. They are deprecated as of Spring Framework 7 in favor of
161160
https://jspecify.dev/docs/start-here/[JSpecify] annotations, which provide significant enhancements such as properly
162161
defined specifications, a canonical dependency with no split-package issue, better tooling, better Kotlin integration
163-
and the capability to specify the nullness more precisely for more use cases.
162+
and the capability to specify the nullability more precisely for more use cases.
164163

165-
A key difference is that Spring null-safety annotations, following JSR 305 semantics, apply to fields,
164+
A key difference is that Spring deprecated null-safety annotations, following JSR 305 semantics, apply to fields,
166165
parameters and return values while JSpecify annotations apply to type usages. This subtle difference
167166
is in practice pretty significant, as it allows for example to differentiate the nullness of elements from the
168167
nullness of arrays/varargs as well as defining the nullness of generic types.
@@ -171,7 +170,7 @@ That means array and varargs null-safety declarations have to be updated to keep
171170
`@Nullable Object[] array` with Spring annotations needs to be changed to `Object @Nullable [] array` with JSpecify
172171
annotations. Same for varargs.
173172

174-
It is also recommended to move field and return value annotations closer to the type, for example:
173+
It is also recommended to move field and return value annotations closer to the type on the same line, for example:
175174

176175
- For fields, instead of `@Nullable private String field` with Spring annotations, use `private @Nullable String field`
177176
with JSpecify annotations.

0 commit comments

Comments
 (0)