Annotation Interface NullUnmarked


@Documented @Retention(RUNTIME) @Target({PACKAGE,TYPE,METHOD,CONSTRUCTOR}) public @interface NullUnmarked
Indicates that the annotated element and the code transitively enclosed within it is null-unmarked code: there, type usages generally have unspecified nullness unless explicitly annotated otherwise.

This annotation's purpose is to ease migration of a large existing codebase to null-marked status. It makes it possible to "flip the default" for new code added to a class or package even before that class or package has been fully migrated. Since new code is the most important code to analyze, this is strongly recommended as a temporary measure whenever necessary. However, once a codebase has been fully migrated it would be appropriate to ban use of this annotation.

For a comprehensive introduction to JSpecify, please see jspecify.org.

Warning: These annotations are under development, and any aspect of their naming, locations, or design is subject to change until the JSpecify 1.0 release. Moreover, supporting analysis tools will track with these changes on varying schedules. Releasing a library using these annotations in its API is strongly discouraged at this time.

Null-marked and null-unmarked code

NullMarked and this annotation work as a pair to include and exclude sections of code from null-marked status (respectively). Specifically, code is considered null-marked if the most narrowly enclosing element annotated with either of these two annotations exists and is annotated with @NullMarked.

Otherwise it is considered null-unmarked. This can happen in two ways: either it is more narrowly enclosed by a @NullUnmarked-annotated element than by any @NullMarked-annotated element, or neither annotation is present on any enclosing element. No distinction is made between these cases.

The effects of being null-marked are described in the Effects section of NullMarked.

Unspecified nullness

Within null-unmarked code, a type usage with no nullness annotation has unspecified nullness (Why?). This means that, while there is always some correct way to annotate it for nullness, that information is missing: we do not know whether it includes or excludes null as a value. In such a case, tools can vary widely in how strict or lenient their enforcement is, or might make it configurable.

For more, please see this more comprehensive discussion of unspecified nullness.

There is no way for an individual type usage within null-marked code to have unspecified nullness. (Why?)

Where it can be used

The information in the Where it can be used section of NullMarked applies as well to this annotation.