Files
kotlin-fork/third-party/java8-annotations/org/jspecify/annotations/Nullable.java
T

145 lines
8.5 KiB
Java

/*
* 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 {}