# Annotation Interface NullMarked

@Documented @Target({MODULE,PACKAGE,TYPE,METHOD,CONSTRUCTOR}) @Retention(RUNTIME) public @interface NullMarked
Indicates that the annotated element and the code transitively enclosed within it are null-marked code: there, type usages are generally considered to exclude `null` as a value unless specified otherwise. Using this annotation avoids the need to write `@NonNull` many times throughout your code.

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

## Effects of being null-marked

Within null-marked code, as a general rule, a type usage is considered non-null (to exclude `null` as a value) unless explicitly annotated as `Nullable`. However, there are several special cases to address.

### Special cases

Within null-marked code:

- We might expect the type represented by a wildcard (like the `?` in `List<?>`) to be non-null, but it isn't necessarily. It's non-null only if it `extends` a non-null type (like in `List<? extends String>`), or if the class in use accepts only non-null type arguments (such as if `List` were declared as `class List<E extends String>`). But if `List` does accept nullable type arguments, then the wildcards seen in `List<?>` and `List<? super String>` must include `null`, because they have no "upper bound". (Why?)
  - Conversely, a type parameter is always considered to have an upper bound; when none is given explicitly, `Object` is filled in by the compiler. The example `class MyList<E>` is interpreted identically to `class MyList<E extends Object>`: in both cases the type argument in `MyList<@Nullable Foo>` is out-of-bounds, so the list elements are always non-null. (Why?)
- Otherwise, being null-marked has no consequence for any type usage where `@Nullable` and `@NonNull` are not applicable, such as the root type of a local variable declaration.
- When a type variable has a nullable upper bound, such as the `E` in `class Foo<E extends @Nullable Bar>`), an unannotated usage of this type variable is not considered nullable, non-null, or even of "unspecified" nullness. Rather it has parametric nullness. In order to support both nullable and non-null type arguments safely, the `E` type itself must be handled strictly: as if nullable when "read from", but as if non-null when "written to". (Contrast with `class Foo<E extends Bar>`, where usages of `E` are simply non-null, just like usages of `String` are.)
- By using `NullUnmarked`, an element within null-marked code can be excluded and made null-unmarked, exactly as if there were no enclosing `@NullMarked` element at all.

## Where it can be used

`@NullMarked` and `@NullUnmarked` can be used on any package, class, method, or constructor declaration; `@NullMarked` can be used on a module declaration as well. Special considerations:

- To apply this annotation to an entire (single) package, create a `package-info.java` file there. This is recommended so that newly-created classes will be null-marked by default. This annotation has no effect on "subpackages". Warning: if the package does not belong to a module, be very careful: it can easily happen that different versions of the package-info file are seen and used in different circumstances, causing the same classes to be interpreted inconsistently. For example, a package-info file from a `test` source path might hide the corresponding one from the `main` source path, or generated code might be compiled without seeing a package-info file at all.
- Although Java permits it to be applied to a record component declaration (as in `record Foo(@NullMarked String bar) {...}`), this annotation has no meaning when used in that way.
- Applying this annotation to an instance method of a generic class is acceptable, but is not recommended because it can lead to some confusing situations.
- An advantage of Java modules is that you can make a lot of code null-marked with just a single annotation (before the `module` keyword). `NullUnmarked` is not supported on modules, since it's already the default.
- If both `@NullMarked` and `@NullUnmarked` appear together on the same element, neither one is recognized.