我是否需要在实施时再次@Nonnull?

Do I need to @Nonnull again at the implementation?

虽然我认为应该有一个关于是否继承注释的通用规则,但我特别感兴趣的是让 FindBugs 识别我的规则,所以这个问题是 FindBugs 特定的。

据我所知,JavaDoc 注释取自接口并在实现时被忽略。这个概念是否也适用于像 @Nonnull(或 @NotNull)这样的注释?

鉴于 @Override 注释,至少可以添加界面上不存在的其他注释。

以下情况会怎样? FindBugs 会识别所有这些吗?哪一个是关于干净代码的首选?

  1. 接口 @Nonnull,实现 @Override
  2. 接口 @Nonnull,实现 @Override@Nonnull
  3. 接口没有注释,实现 @Override,@Nonnull`

接口上的注释声明所有实现不得 return null 而实现上的注释声明它遵守该合同。它不是遗传的,我认为也不是。

@CheckForNull 注释绝对不会被继承,因为子类可以缩小 return 类型的空性,就像它们可以为它们接受的参数加宽它一样。

interface Credentials {
    @NonNull
    String getPassword();

    void setPassword(@NonNull password);
}

// Allows null password
class GoodCreds implements Credentials {
    // but cannot widen; throw exception for null instead
    @Overrides
    @NonNull
    String getPassword() {...}

    // can widen parameters
    @Overrides
    void setPassword(@CheckForNull password) {...}
}

Note: I'll add matching username accessors to demonstrate bad widening in a BadCreds subclass when I have time later.

选择选项 2:

  1. Interface @Nonnull, Implementation @Override @Nonnull

如果 FindBugs 和许多其他工具(如 IDE)在正确的位置找到注释,它们会做得更好。这些注释不是继承的,正如 this section 底部的 JLS 状态:

Annotation inheritance only works on classes (not methods, interfaces, or constructors)

所以工具需要自己去寻找它们。有些工具可以做到这一点,但即使是 FindBugs 也不能始终如一地做到这一点(我最后检查过)。