You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improve null-safety documentation related to TYPE_USE
This commit refines the null-safety documentation to document more
explicitly the code style guidelines related to
`@Target(ElementType.TYPE_USE)`.
Closesgh-35098
A key difference between JSpecify `@Nullable` / `@NonNull` annotations and most other variants is that they are
71
+
meta-annotated with `@Target(ElementType.TYPE_USE)`, so they apply only to type usages. This impacts where such
72
+
annotations should be placed, either to comply with
73
+
https://docs.oracle.com/javase/specs/jls/se17/html/jls-9.html#jls-9.7.4[related Java specifications] or to follow code
74
+
style best practices. From a style perspective, it is recommended to embrace the type-use nature of those annotations by placing them on the
75
+
same line than the annotated type.
66
76
67
77
For example, for a field:
68
78
@@ -75,8 +85,8 @@ Or for method parameters and method return types:
75
85
76
86
[source,java,subs="verbatim,quotes"]
77
87
----
78
-
public static @Nullable String buildMessage(@Nullable String message,
79
-
@Nullable Throwable cause) {
88
+
public @Nullable String buildMessage(@Nullable String message,
89
+
@Nullable Throwable cause) {
80
90
// ...
81
91
}
82
92
----
@@ -88,24 +98,41 @@ method. That means the JSpecify annotations should be copied to the overriding m
88
98
you want to override the implementation and keep the same nullability semantics.
89
99
====
90
100
101
+
https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html[`@NonNull`] and
102
+
https://jspecify.dev/docs/api/org/jspecify/annotations/NullUnmarked.html[`@NullUnmarked`] should rarely be needed for
103
+
typical use cases.
104
+
105
+
==== Arrays and varargs
106
+
91
107
With arrays and varargs, you need to be able to differentiate the nullness of the elements from the nullness of
92
108
the array itself. Pay attention to the syntax
93
109
https://docs.oracle.com/javase/specs/jls/se17/html/jls-9.html#jls-9.7.4[defined by the Java specification] which may be
94
-
initially surprising:
110
+
initially surprising. For example, in `@NullMarked` code:
95
111
96
112
- `@Nullable Object[] array` means individual elements can be null but the array itself cannot.
97
113
- `Object @Nullable [] array` means individual elements cannot be null but the array itself can.
98
114
- `@Nullable Object @Nullable [] array` means both individual elements and the array can be null.
99
115
116
+
==== Generics
117
+
118
+
JSpecify annotations applies to generics as well. For example, in `@NullMarked` code:
119
+
120
+
- `List<String>` means a list of non-null elements (equivalent of `List<@NonNull String>`)
121
+
- `List<@Nullable String>` means a list of nullable elements
122
+
123
+
Things are a bit more complicated when you are declaring generic types or generic methods, see related
124
+
https://jspecify.dev/docs/user-guide/#generics[JSpecify generics documentation] for more details.
125
+
126
+
WARNING: Generic types and generic methods nullability https://github.com/uber/NullAway/issues?q=is%3Aissue+is%3Aopen+label%3Ajspecify[is not yet fully supported by NullAway].
127
+
128
+
==== Nested and fully qualified types
129
+
100
130
The Java specification also enforces that annotations defined with `@Target(ElementType.TYPE_USE)` like JSpecify
101
131
`@Nullable` should be specified after the last `.` with inner or fully qualified types:
102
132
103
-
- `Cache.@Nullable ValueWrapper`
104
-
- `jakarta.validation.@Nullable Validator`
133
+
- `Cache.@Nullable ValueWrapper`
134
+
- `jakarta.validation.@Nullable Validator`
105
135
106
-
https://jspecify.dev/docs/api/org/jspecify/annotations/NonNull.html[`@NonNull`] and
107
-
https://jspecify.dev/docs/api/org/jspecify/annotations/NullUnmarked.html[`@NullUnmarked`] should rarely be needed for
108
-
typical use cases.
109
136
110
137
[[null-safety-guidelines-nullaway]]
111
138
=== NullAway
@@ -126,7 +153,7 @@ parameter cannot be null after a successful invocation of `Assert.notNull()`.
126
153
127
154
Optionally, it is possible to set `NullAway:JSpecifyMode=true` to enable
128
155
https://github.com/uber/NullAway/wiki/JSpecify-Support[checks on the full JSpecify semantics], including annotations on
129
-
generic types. Be aware that this mode is
156
+
arrays, varargs and generics. Be aware that this mode is
130
157
https://github.com/uber/NullAway/issues?q=is%3Aissue+is%3Aopen+label%3Ajspecify[still under development] and requires
131
158
using JDK 22 or later (typically combined with the `--release` Java compiler flag to configure the
132
159
expected baseline). It is recommended to enable the JSpecify mode only as a second step, after making sure the codebase
0 commit comments