这是使用JSR305中javax.annotation的正确方法吗?

这是使用JSR305中javax.annotation的正确方法吗?,java,api,annotations,Java,Api,Annotations,我最近将RI for JSR305添加到我的项目中,并向我的接口添加注释,如下所示: public interface AccountService { @Nullable AccountResult consolidate( @Nonnull Date from, @Nonnull Date to ) } 本着JSR的精神(如本文所述),您认为我在接口中使用注释是在误用注释吗?我想指出返回值可以为null,但我认为@Nullable更适用于方法“consolidate”。我不会将它们

我最近将RI for JSR305添加到我的项目中,并向我的接口添加注释,如下所示:

public interface AccountService
{
    @Nullable AccountResult consolidate( @Nonnull Date from, @Nonnull Date to )
}

本着JSR的精神(如本文所述),您认为我在接口中使用注释是在误用注释吗?我想指出返回值可以为null,但我认为@Nullable更适用于方法“consolidate”。我不会将它们添加到实现中,因为当我编码时,接口的代码是我的指路明灯

我认为这取决于添加注释的原因

如果您只是添加它们以供参考,以便接口的实现者了解您的预期设计,那么这很好

我使用注释进行事务处理和安全角色实施,因此注释处于实现级别。这一点的好处在于,我的Spring容器中的AOP处理器可以测试是否存在这个或那个注释,并应用适当的代理类来执行定义事务边界或确保用户被授权进行某些特定的方法调用等操作


所以,如果您计划对注释的存在或不存在的任何处理设置关键帧,请确保您的实现已注释。如果只是供参考,可以只注释接口。

您可以将“@NonNull String”视为String的严格子类。毕竟,任何非空字符串都肯定是“@Nullable String”的“instanceof”,但任何“@Nullable String”的instanceof都可能不是“@NonNull String”的实例(例如,如果它是空的,就不会是)

从这个角度来看,@Nullable和@NonNull是类型信息,因此在接口中是完全合理的。您向实现者指示他们可能返回null,并且他们不必担心输入null,并且您向调用者指示他们不能传入null,并且应该期望传出null

当然,尽管这一切都很合理,但vanilla javac v1.6肯定不会像它对实际类型强制执行类型安全那样强制执行这些规则。但是人们可以做梦,或者使用pmd或findbugs之类的东西来验证这些注释

然而,@NonNull和@Nullable注释对于完整的空类型系统来说是不够的。我真的不知道为什么JSR305没有解决这个问题,但是还有第三种类型:“@MaybeNull”。它将显示在泛型参数内部;在其他任何地方,它都具有与@Nullable相同的含义

公共静态无效addIfNotNull(列表,@Nullable T项){ 如果(项目!=null)列表。添加(项目); }

如果第一个“T”上的注释为“@Nullable”,则无法传入非空列表,这将成为一个非常无用的API。另一方面,如果它是@NonNull,则无法在中传递可为null的列表。实际上,无论您在其中移动什么,它(A)永远不会导致NullPointerException,并且(B)永远不会违反注释。所以,你需要一种表达方式:我不在乎这个特殊的't'是否可以为null;当我读它的时候,我会检查空值,而且我永远不会写空值,所以这没关系

@MaybeNull和@Nullable之间的区别类似于“?扩展泛型中的“Number”和“Number”。在泛型之外,它们的意思是相同的,但在泛型中有区别

所以,不要期望在短时间内进行严格的打字检查


@继承只适用于类,但对于带注释的返回类型和带注释的参数,可以想象类似的情况。

除了您想要表达的含义(返回值可以为null)之外,对可为null的方法的另一种解释是什么?@MaybeNull是从JSR305中废弃的,据我所知。此外,关于泛型类型的注释由JSR308指定,它将在Java7中可用。(注意:只会启用无法注释泛型类型这一事实,而不会启用预定义注释的整个集合。)