-
Notifications
You must be signed in to change notification settings - Fork 26
/
Nullable.java
144 lines (141 loc) · 8.48 KB
/
Nullable.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
* Copyright 2018-2020 The JSpecify Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jspecify.annotations;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Indicates that the annotated <a href="https://github.com/jspecify/jspecify/wiki/type-usages">type
* usage</a> (commonly a parameter type or return type) is considered to include {@code null} as a
* value.
*
* <p>Example usages:
*
* <pre>{@code
* @Nullable String field;
*
* @Nullable String getField() { return field; }
*
* void setField(@Nullable String value) { field = value; }
*
* List<@Nullable String> getList() { … }
* }</pre>
*
* <p>For a comprehensive introduction to JSpecify, please see <a
* href="http://jspecify.org">jspecify.org</a>.
*
* <p><b>Warning:</b> These annotations are under development, and <b>any</b> aspect of their
* naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover,
* supporting analysis tools will be tracking the changes on varying schedules. Releasing a library
* using these annotations in its API is <b>strongly discouraged</b> at this time.
*
* <h2>Meaning per each kind of type usage</h2>
*
* <p>The essential meaning of this annotation is always the same: the type it annotates is
* considered to include {@code null} as a value. But this may affect your code a little differently
* based on the kind of type usage involved.
*
* <ul>
* <li>On a <b>parameter type</b>: The {@code setField} method (at top) permissively accepts a
* "string-or-null", meaning that it is okay to pass an actual string, or to pass {@code
* null}. (This doesn't guarantee that passing {@code null} won't produce an exception at
* runtime, but it should be much less likely.) This also applies to the type of a lambda
* expression parameter, if that type is given explicitly (otherwise its nullness must be
* inferred from context).
* <li>On a <b>method return type</b>: The {@code getField} method returns a "string-or-null", so
* while the caller might get a string back, it should also address the possibility of getting
* {@code null} instead. (This doesn't guarantee there is any circumstance in which {@code
* null} <i>will</i> actually be returned.)
* <li>On a <b>field type</b>: The {@code field} field has the type "string-or-null", so at times
* it might hold a string, and at times it might hold {@code null}. (Of course, every field of
* a reference type <i>originally</i> holds {@code null}, but as long as the class ensures
* that its uninitialized states can't be observed, it's appropriate to overlook that fact.)
* <li>On a <b>type argument</b>: A type usage of "nullable string" appears <i>within</i> the
* compound type {@code List<@Nullable String>}. No matter how this type is used (return type,
* etc.), this means the same thing: every appearance of {@code E} in {@code List}'s member
* signatures will be considered nullable. For a list, this means it may contain null
* <i>elements</i>. If the list reference itself might be null as well, we can write
* {@code @Nullable List<@Nullable String>}, a "nullable list of nullable strings".
* <li>On the upper bound of a <b>type parameter</b>: For example, as seen in {@code class List<E
* extends @Nullable Object>}. This means that a <i>type argument</i> supplied for that type
* parameter is permitted to be nullable if desired: {@code List<@Nullable String>}. (A
* non-null type argument, as in {@code List<String>}, is permitted either way.)
* <li>On a usage of a <b>type variable</b>: A type parameter, like the {@code E} in {@code
* interface List<E>}, defines a "type variable" of the same name, usable only <i>within</i>
* the scope of the declaring API element. In any example using {@code String} above, a type
* variable like {@code E} might appear instead. {@code @Nullable} continues to mean "or null"
* as always, but notably, this works without regard to whether the type argument is
* <i>already</i> nullable. For example, suppose that {@code class Foo<E extends @Nullable
* Object>} has a method {@code @Nullable E eOrNull()}. Then, whether {@code foo} is of type
* {@code Foo<String>} or {@code Foo<@Nullable String>}, the expression {@code foo.eOrNull()}
* is nullable either way. Using {@code @Nullable E} in this way is called "nullable
* projection" (<a href="NonNull.html#projection">non-null projection</a> is likewise
* supported, but less commonly useful).
* <li>On a <b>nested type</b>: In most examples above, in place of {@code String} we might use a
* nested type such as {@code Map.Entry}. The Java syntax for annotating such a type as
* nullable looks like {@code Map.@Nullable Entry}.
* <li>On a <b>record component</b>: As expected, {@code @Nullable} here applies equally to the
* corresponding parameter type of the canonical constructor, and to the return type of a
* generated accessor method as well. If an explicit accessor method is provided for this
* record component, it must still be annotated explicitly. Any non-null components should be
* checked (for example using {@link java.util.Objects#requireNonNull}) in a <a
* href="https://docs.oracle.com/en/java/javase/19/language/records.html">compact
* constructor</a>.
* </ul>
*
* <h2 id="applicability">Where it is applicable</h2>
*
* <p>This annotation and {@link NonNull} are applicable to any <a
* href="https://github.com/jspecify/jspecify/wiki/type-usages">type usage</a> <b>except</b> the
* following cases, where they have no defined meaning:
*
* <ul>
* <li>On any<b> intrinsically non-null type usage</b>. Some type usages are incapable of
* including {@code null} by the rules of the Java language. Examples include any usage of a
* primitive type, the argument to {@code instanceof}, a method return type in an annotation
* interface, or the type following {@code throws} or {@code catch}. In such locations, a
* nullness annotation could only be contradictory ({@code @Nullable}) or redundant
* ({@code @NonNull}).
* <li>On the root type of a <b>local variable</b> declaration. The nullness of a local variable
* itself is not a fixed declarative property of its <i>type</i>. Rather it should be inferred
* from the nullness of each expression assigned to the variable, possibly changing over time.
* (<a href="https://bit.ly/3ppb8ZC">Why?</a>). Subcomponents of the type (type arguments,
* array component types) are annotatable as usual.
* <li>On the root type in a <b>cast expression</b>. To inform an analyzer that an expression it
* sees as nullable is truly non-null, use an assertion or a method like {@link
* java.util.Objects#requireNonNull}. (<a href="https://bit.ly/3ppb8ZC">Why?</a>)
* Subcomponents of the type (type arguments, array component types) are annotatable as usual.
* <li>On any part of a <b>receiver parameter</b> type (<a
* href="https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.4">JLS 8.4</a>).
* <li>If both {@code @Nullable} and {@code @NonNull} appear on the same type usage,
* <i>neither</i> one is recognized.
* </ul>
*
* Whether the code is {@link NullMarked} also has no consequence in the above locations.
*
* <h2>Unannotated type usages</h2>
*
* <p>For a type usage where nullness annotations are <a href="#applicability">applicable</a> but
* not present, its nullness depends on whether it appears within {@linkplain NullMarked
* null-marked} code; see that class for details. Note in particular that nullness information from
* a superclass is never automatically "inherited".
*/
@Documented
@Target(TYPE_USE)
@Retention(RUNTIME)
public @interface Nullable {}