Annotation Interface NullUnmarked
This annotation's purpose is to ease progressive migration of a large codebase. If some class or package can't be fully migrated yet, you can still make it null-marked by using this annotation on the portions that still need work. This practice is useful because it flips the default for new code added later, which is the most important code to analyze.
Once a codebase has been fully migrated it would be reasonable to ban use of this annotation.
For important information common to all four nullness annotations, see org.jspecify.annotations. To learn more about JSpecify, see jspecify.dev.
Null-marked and null-unmarked contexts
NullMarked puts enclosed code in null-marked context; this annotation puts it in
null-unmarked context instead. These annotations work as an inclusion-exclusion pair: of the
annotations of either type on all enclosing elements (methods, classes, etc.), only the
nearest (most narrowly enclosing) one is in effect.
Otherwise, code is in null-unmarked context. 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 context, a type usage that is nullness-applicable but has no nullness annotation generally has unspecified nullness (Why?). This means
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 even be
configurable.
For more, please see this more comprehensive discussion of unspecified nullness.
There is no way for an individual type usage within null-marked context 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.