NullableTypeParameter
Nullness annotations directly on type parameters are interpreted differently by different tools

Severity
WARNING

The problem

Nullness annotations directly on type parameters are interpreted differently by different tools. — unless you are using the Checker Framework.

Tool interpretations and suggested alternatives

class Foo<@Nullable T>

To the Checker Framework, this means that a given type argument must be nullable. For example, in the Checker Framework’s default JDK stubs, the type argument to ThreadLocal must be nullable.

To Kotlin, this means that the type argument can be nullable but need not be so.

If you want the Checker Framework interpretation, then keep your code as it is, and suppress this warning. If you want the “can be nullable” interpretation, change to class Foo<T extends @Nullable Object>.

The effects of that change would be:

class Foo<@NonNull T>

To the Checker Framework, this means to allow any nullness for the type argument(!). (It sets the lower bound to @NonNull, which is already the default there.)

To Kotlin, this means that the type argument must be non-nullable.

Users probably want class Foo<T extends @NonNull Object>. Or, if they’re within the scope of @NullMarked and they are using tools that recognize it (such as Kotlin), they may prefer class Foo<T>, which is equivalent but shorter.

The effects of that change would be:

JSpecify specification

The JSpecify spec says that usages of their annotations on type parameters are unrecognized (Javadoc, spec). This specification choice is motivated by the disagreement in tool behavior discussed above.

Suppression

Suppress false positives by adding the suppression annotation @SuppressWarnings("NullableTypeParameter") to the enclosing element.