将参数标记为@Nullable 然后在传入 null 时抛出 IllegalArgumentException 是否合适?

Is it proper to mark a param as @Nullable and then throw an IllegalArgumentException when a null is passed in?

所以我只是向我的同事钻研说他不应该像标题所说的那样做。但我为自己的立场而奋斗,以至于我想确保我真的是对的(我想做的最糟糕的事情就是将不正确的意见强加给别人)。

所以基本上我试图验证以下确实是不好的做法:

public void methodA(@Nullable String value) {
  if (value == null) throw new IllegalArgumentException();
  ...
}

他的论点是@Nullable只是说你可以在这里传递一个null,但并不能保证这样做的结果会“很好”。

而我的论点是,这样做违反了合同,即 @Nullable 意味着 null 值将得到妥善处理,而不是被视为 例外

问题是我找不到任何可以实际验证我的声明的文件。

最终我说服了他我的立场,但现在我担心我可能错了。


啊,我在这里遗漏了一些上下文。所以我们使用 Spring 中的 @NonNullApi,默认情况下在所有参数上放置一个 @Nonnull。所以如果你想支持空参数,你需要用 @Nullable 注释覆盖它。

The problem is I can't find any documentation actually verifying my claim.

这是 JetBrains Annotations 库中的一些文档:

Nullable:

An element annotated with Nullable claims null value is perfectly valid to return (for methods), pass to (parameters) or hold in (local variables and fields).

NotNull:

An element annotated with NotNull claims null value is forbidden to return (for methods), pass to (parameters) and hold (local variables and fields).

我会说这样的契约,比如“如果你给这个参数传递一个空值,我肯定会抛出异常!”将使 null 成为传递给该参数的“禁止”值。您应该使用 @NotNull (或类似的)来注释它。传递给该参数肯定不是“完全有效”的值。

当然,您的同事仍然可以争辩说,由于通过 null 编译 ,它是“完全有效的”:) 但这只是 IMO 的诡辩。


我了解到您使用的是 Spring 的注释,但是 Spring 文档中的措辞不如 JetBrains 的强大,这就是我选择后者的原因提出更有力的论据。希望您会同意这两对注释旨在解决相同的问题,并且具有相同的语义。如果您应该将某些内容标记为 org.springframework.lang.Nonnull 而不是 org.jetbrains.annotations.NotNull.

,那将是荒谬的

Checker Framework 手册section "Annotations indicate non-exceptional behavior"支持您的观点。它指出:

You should use annotations to specify normal behavior. The annotations indicate all the values that you want to flow to a reference — not every value that might possibly flow there if your program has a bug.

根据你同事的推理:

His argument was that @Nullable simply states that you can pass a null in here, but it doesn't guarantee that the result of doing so will be "nice".

每个引用类型都可以注释为 @Nullable,因此 @Nullable 没有任何意义。