'@NonNull String' は String の厳密なサブクラスとして表示されます。結局のところ、null 以外の文字列は間違いなく 'instanceof' '@Nullable String' ですが、instanceof '@Nullable String' は '@NonNull String' のインスタンスではない可能性があります ( null の場合はそうではありません)。例えば)。
そのように見ると、 @Nullable と @NonNull は型情報であり、したがってインターフェイスでは完全に合理的です。null を返す可能性があり、入力 null について心配する必要がないことを実装者に示し、null を渡してはならず、null を期待する必要があることを呼び出し元に示しています。
もちろん、これはすべて非常に合理的ですが、vanilla javac v1.6 は、実際の型に対して型安全性を強制する方法で、これらの規則を強制しません。しかし、夢を見ることもできますし、pmd や findbugs のようなものを使ってこれらの注釈を検証することもできます。
ただし、@NonNull および @Nullable アノテーションは、完全な nullity 型付けシステムには十分ではありません。JSR305 がこれに対処しない理由はよくわかりませんが、「@MaybeNull」という 3 番目のタイプがあります。ジェネリック パラメータ内に表示されます。それ以外の場合は、@Nullable と同じ意味になります。
public static void addIfNotNull(List<@MaybeNull T> list, @Nullable T item) { if ( item != null ) list.add(item); }
最初の「T」の注釈が「@Nullable」である場合、null 以外のリストを渡すことができず、かなり役に立たない API になります。一方、@NonNull の場合は、null 許容リストを渡すことができませんでした。実際には、そこに何を移動しても問題ありません。(A) NullPointerException が発生することはなく、(B) 発生することもありません。注釈に違反します。したがって、表現する方法が必要です。この特定の 'T' が Nullable かどうかは気にしません。それから読み取るときにnullチェックを行い、nullを書き込むことはないので、問題ありません。
@MaybeNull と @Nullable の違いは、'? ジェネリックの Number' と 'Number' を拡張します。ジェネリックの外では同じことを意味しますが、ジェネリックでは違いがあります。
したがって、すぐに厳格な型チェックを期待しないでください。
@Inherited はクラスに対してのみ機能しますが、注釈付きの戻り値の型と注釈付きのパラメーターについても同様のことが想像できます。