Вы можете видеть '@NonNull String' как строгий подкласс String. В конце концов, любая ненулевая строка определенно является 'instanceof' '@Nullable String', но любой экземпляр '@Nullable String' может не быть экземпляром '@NonNull String' (это не было бы, если бы оно был ноль, например).
Глядя на это таким образом, @Nullable и @NonNull - это информация о типах, и поэтому они совершенно разумны в интерфейсах. Вы указываете реализаторам, что они могут возвратить ноль, и что им не нужно беспокоиться о вводимых нулях, и вы указываете вызывающим, что они не должны передавать нулевое значение и что они должны ожидать нулевые значения.
Конечно, хотя все это очень разумно, vanilla javac v1.6 определенно не применяет ни одно из этих правил, как это обеспечивает безопасность типов для реальных типов. Но можно мечтать или использовать что-то вроде pmd или findbugs для проверки этих аннотаций.
Однако аннотаций @NonNull и @Nullable недостаточно для полной системы набора недействительности. Я действительно не знаю, почему JSR305 не решает эту проблему, но есть третий тип: "@MaybeNull". Это будет отображаться внутри общих параметров; в любом другом месте это будет иметь то же значение, что и @ Nullable.
public static void addIfNotNull (список List <@MaybeNull T>, элемент @Nullable T) {
if (item! = null) list.add (item);
}
Если в первой букве 'T' есть аннотация "@Nullable", то вы не могли бы передавать ненулевые списки, что создавало бы довольно бесполезный API. С другой стороны, если бы это был @NonNull, вы не могли бы передать в него обнуляемый список. На практике не имеет значения, что вы там перемещаете, это (A) никогда не вызовет исключение NullPointerException, и (B) никогда нарушать аннотацию. Итак, вам нужен способ выразить: мне все равно, является ли этот конкретный 'T' Nullable или нет; Я буду проверять нуль, когда читаю, и никогда не буду писать нули, так что это не имеет значения.
Разница между @MaybeNull и @Nullable аналогична разнице между '? расширяет Number 'и' Number 'в генериках. За пределами дженериков они означают одно и то же, но в дженериках есть разница.
Так что не надейтесь в ближайшее время на жесткую проверку типов.
@ Наследование работает только для классов, но можно представить что-то похожее для аннотированных типов возвращаемых данных и аннотированных параметров.