我最近将JSR305的RI添加到我的项目中,并一直在为我的接口添加注释,如下所示:
public interface AccountService
{
@Nullable AccountResult consolidate( @Nonnull Date from, @Nonnull Date to )
}按照JSR的精神(如这里所述),您认为我在接口中使用注解是不是误用了它们?我想指出返回值可以为null,但我认为@Nullable更适用于"consolidate“方法。我没有将它们添加到实现中,因为当我编写代码时,接口的代码就是我的指路灯。
发布于 2009-08-15 22:00:40
您可以将“@NonNull String”视为String的严格子类。毕竟,任何非空字符串肯定是' instanceof‘'@Nullable String',但任何'@Nullable String’的实例可能不是'@NonNull String‘的实例(例如,如果它是null,就不是)。
从这个角度来看,@Nullable和@NonNull是类型信息,因此在接口中是完全合理的。您是在向实现者表明他们可以返回null,并且他们不必担心输入null,并且您是在向调用者表明他们不能传入null,并且他们应该期待null输出。
当然,虽然这一切都很合理,但vanilla javac v1.6肯定不会像它为实际类型强制类型安全那样强制执行这些规则中的任何一条。但是你可以做梦,或者你可以使用像pmd或findbugs这样的东西来验证这些注解。
然而,@NonNull和@Nullable注释对于一个完整的空性类型系统来说是不够的。我真的不知道为什么JSR305没有解决这个问题,但是还有第三种类型:"@MaybeNull“。它将显示在泛型参数中;在其他任何地方,它都与@Nullable具有相同的含义。
public static void addIfNotNull(List<@MaybeNull T> list,@ null T item) { if ( item != null) list.add(item);}
如果第一个'T‘上的注解是"@Nullable",那么你就不能传入非空列表,这会使API变得非常无用。另一方面,如果它是@NonNull,则不能传入一个可以为空的列表。实际上,您在其中移动的内容并不重要,它(A)永远不会导致NullPointerException,(B)永远不会违反注释。所以,你需要一种方式来表达:我不关心这个特殊的'T‘是否可以为空;当我从它读取时,我将进行空检查,并且我永远不会写空,所以这并不重要。
@MaybeNull和@Nullable之间的区别类似于'?在泛型中扩展Number‘和'Number’。在泛型之外,它们的含义是相同的,但在泛型中是不同的。
所以,短期内不要对严格的类型检查寄予厚望。
@Inherited只适用于类,但可以想象类似于带注释的返回类型和带注释的参数。
发布于 2009-08-06 20:43:47
我认为这取决于您添加注释的原因。
如果您只是添加它们以供参考,以便接口的实现者知道您的预期设计,那么这是很好的。
我将注释用于事务处理和安全角色强制,因此我的注释位于实现级别。这样做的好处是,我的Spring容器中的AOP处理器可以测试这个或那个注释的存在,并应用适当的代理类来做一些事情,比如定义事务边界或确保用户被授权进行某些特定的方法调用。
因此,如果您计划对注释的存在或不存在进行任何处理,请确保您的实现已被注释。如果只是作为参考,可以只对接口进行注释。
https://stackoverflow.com/questions/855818
复制相似问题