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

Jac*_*ine 5 java api annotations

我最近将JSR305的RI添加到我的项目中,并且一直在为我的接口添加注释,如下所示:

public interface AccountService
{
    @Nullable AccountResult consolidate( @Nonnull Date from, @Nonnull Date to )
}
Run Code Online (Sandbox Code Playgroud)

本着JSR的精神(如此处所述),你认为我在界面中使用它们会误用注释吗?我想指出返回值可以为null但我认为@Nullable更多地应用于方法"合并".我没有将它们添加到实现中,因为当我编码时,接口的代码是我的指路明灯.

小智 6

您可以将'@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仅适用于类,但可以想象类似于带注释的返回类型和带注释的参数.


non*_*ont 1

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

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

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

因此,如果您计划根据注释的存在或不存在来控制任何处理,请确保您的实现已注释。如果只是为了参考,只注释接口就可以了。