Nullness annotations directly on wildcard types are interpreted differently by different tools. β unless you are using the Checker Framework.
Foo<@Nullable ?>
To the Checker Framework, this means that the type argument must be nullable.
They use this
in ExecutorService
.
To Kotlin, this has no effect. That means that the type argument can be nullable but need not be so.
While Checker Framework users do sometimes want Foo<@Nullable ?>
, we commonly
see them use it in places where Foo<?>
would also be correct and would be more
flexible. To fully preserve Kotlin behavior, Kotlin users may wish to write
βFoo<? extends @Nullable Object>
β (unless they are within the scope of
@NullMarked
, in which case Foo<?>
is equivalent).
The effects of that change would be:
ExecutorService
and the Future
objects that it produces.Foo<?>
is probably not a behavior change for Kotlin.Foo<@NonNull ?>
To the Checker Framework, this means that the type argument must be non-nullable. (See the Checker Framework docs.)
To Kotlin, this has no effect. That means that the type argument can still be nullable.
We recommend a change to Foo<? extends @NonNull Object>
(or, within the scope
of @NullMarked
, Foo<? extends Object>
).
The effects of that change would be:
The JSpecify spec says that usages of their annotations on wildcard types are unrecognized (Javadoc, spec). This specification choice is motivated by the disagreement in tool behavior discussed above.
Suppress false positives by adding the suppression annotation @SuppressWarnings("NullableWildcard")
to the enclosing element.