您可以将’@NonNull String’视为String的严格子类.毕竟,任何非null的String肯定是’instanceof”@ Nullable String’,但是’@Nullable String’的任何实例都可能不是’@NonNull String’的实例(如果它是null,则不会是例如).
以这种方式看,@ Nullable和@NonNull是类型信息,因此在接口中非常合理.您向实现者指出它们可能返回null,并且它们不必担心输入空值,并且您向调用者指示它们不能传入null,并且它们应该期望空值.
当然,虽然这一切都非常合理,但vanilla javac v1.6肯定不会强制执行任何这些规则,因为它强制实际类型的类型安全.但是人们可以梦想,或者可以使用像pmd或findbugs这样的东西来完成验证这些注释的工作.
但是,对于完整的无效类型系统,@ NonNull和@Nullable注释是不够的.我真的不知道为什么JSR305没有解决这个问题,但还有第三种类型:“@ MaybeNull”.它会显示在泛型参数内部;在任何其他地方,它与@Nullable具有相同的含义.
public static void addIfNotNull(List< @MaybeNull T> list,@ Nullable T item){
if(item!= null)list.add(item);
}
如果第一个’T’上的注释有“@Nullable”,那么你就无法传递非空列表,这会导致一个相当无用的API.另一方面,如果它是@NonNull,你就无法传递一个可空的列表.在实践中,你在那里移动并不重要,它将(A)永远不会导致NullPointerException,并且(B)从不违反了注释.所以,你需要一种表达方式:我不在乎这个特定的’T’是否可以为空;当我从中读取时,我将进行空检查,并且我永远不会写空值,所以无所谓.
@MaybeNull和@Nullable之间的区别类似于’?在泛型中扩展Number’和’Number’.除了泛型之外,它们的意思相同,但在泛型中却存在差异.
所以,不要让你的希望很快得到严格的类型检查.
@Inherited仅适用于类,但可以想象类似于带注释的返回类型和带注释的参数.