我在一个开发人员使用不同 IDE(Eclipse、Netbeans 和 IntelliJ)的环境中工作。我正在使用 @Nonnull 注释 (javax.annotation.Nonnull) 来指示方法永远不会返回 null:
@Nonnull
public List<Bar> getBars() {
return bars; // this.bars is a final, initialized list
}
我希望其他开发人员在执行以下操作时收到警告:
- 在不移除@Nonnull 注释的情况下更改返回 null 的方法
- 不必要地检查用@Nonnull 显式定义的方法是否为 null:if (foo.getBars() == null) { ... do something ... }
支持第一种情况,例如通过 IntelliJ。第二个不是;不会警告客户端检查 null 是不必要的。
在任何情况下,我们都计划转向返回集合的克隆而不是集合本身,所以最好忘记 @Nonnull 并改为执行此操作:
public List<Bar> getBars() {
return new ArrayList<Bar>(bars);
}
编辑:
澄清一下,我没有考虑为此更改 IDE。我想知道上述 IDE 是否支持我上面描述的内容 - 或者,是否有充分的理由说明为什么不支持它。
我明白了不要过分依赖契约(Contract)的意思。但是,如果我用最后一段中的样式编写 getBars() (返回列表的克隆),那么例如IntelliJ 会为任何执行此操作的代码标记警告
if (foo.getBars() == null) { ... }
如果您选择遵循此警告并删除 null 检查,您似乎同样依赖于 getBars() 实现不变。但是,在这种情况下,您似乎依赖于实现细节而不是显式契约(Contract)(@Nonnull 就是这种情况)。
编辑#2:
我不关心执行速度,null 检查确实非常快。我担心代码的可读性。考虑以下几点:
选项 A:
if ((foo.getBars() == null || foo.getBars().size() < MAXIMUM_BARS) &&
(baz.getFoos() == null || baz.getFoos().size() < MAXIMUM_FOOS)) {
// do something
}
选项 B:
if (foo.getBars().size() < MAXIMUM_BARS &&
baz.getFoos().size() < MAXIMUM_FOOS) {
// do something
}
我认为选项 B 比选项 A 更具可读性。由于阅读代码的次数多于编写代码的次数,因此我想确保我(以及我们团队中的其他人)编写的所有代码都尽可能具有可读性。
最佳答案
我会推荐以下内容:
- 坚持使用您的
@Nonnull
和@Nullable
注释,就像您已经在做的那样。 - 定义并执行默认值。默认值是什么并不重要,但整个代码库中的默认值应该相同。
- 使用FindBugs检查您的案例 1 和 2。FindBugs 有适用于大多数 IDE 的插件,我看到提到了 Eclipse、Netbeans 和 IntelliJ,但还有更多。 (第 2 种情况包含在 RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE 规则中。我测试了它。我只是想在阅读本页其他地方的 DavidHarkness 评论后提及这一点。)
这种方法与 IDE 无关,也适用于 Hudson 或 Jenkins 等外部构建环境。
关于java - @Nonnull 与不同的 IDE - 警告不必要的空检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21375867/