| Nullness annotations directly on wildcard types are interpreted differently by |
| different tools. |
| — unless you are using the Checker Framework. |
| |
| ### Tool interpretations and suggested alternatives |
| |
| #### `Foo<@Nullable ?>` |
| |
| To the Checker Framework, this means that the type argument *must* be nullable. |
| They use this |
| [in `ExecutorService`](https://github.com/typetools/jdk/blob/1973fa0811588dd0bb025fdc99345cdb887b3b52/src/java.base/share/classes/java/util/concurrent/ExecutorService.java#L269). |
| |
| To Kotlin, this [has no effect][KT-40498]. 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: |
| |
| * It is a behavior change for the Checker Framework, one that could produce |
| local or non-local the Checker Framework failures. But it's likely to be a |
| desirable change except in the context of `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](https://checkerframework.org/manual/#annotations-on-wildcards).) |
| |
| To Kotlin, this [has no effect][KT-40498]. 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: |
| |
| * It is a no-op for the Checker Framework. |
| * It could produce errors for Kotlin users. But these errors are likely to be |
| what was intended all along. |
| |
| ### JSpecify specification |
| |
| The JSpecify spec says that usages of their annotations on wildcard types are |
| unrecognized |
| ([Javadoc](https://jspecify.dev/docs/api/org/jspecify/annotations/Nullable.html#applicability), |
| [spec](https://jspecify.dev/docs/spec/#recognized-locations-for-type-use-annotations)). |
| This specification choice is motivated by the disagreement in tool behavior |
| discussed above. |
| |
| [KT-40498]: https://youtrack.jetbrains.com/issue/KT-40498/Nullability-annotations-on-Java-wildcard-itself |