我们应该始终使用@NotNull 还是@Nullable?

Should we always use @NotNull or @Nullable?

我们是否应该始终在方法参数中使用 @NotNull@Nullable,即使它看起来很明显?

@NotNull
public static int add(@NotNull int a, @NotNull int b) {
    return a + b;
}

澄清:

现在我知道不能将 null 传递给原始变量,但我想问一下如果我有一个方法(带有非原始参数)可以将 null 传递给passed 但从方法的名称可以看出你不能传递 null 因为例如,你不能添加一些东西到 null?

@NotNull
public static Integer add(@NotNull Integer a, @NotNull Integer b) {
    return a + b;
}

在 Java 原始类型中,例如 int 永远不会是 null,这是由编译器强制执行的,因此代码中的注释是完全不必要的。

即使您设法将 Integer 作为参数传递(通过自动拆箱),在大多数情况下也不允许使用 null 值:

add(1, (Integer) null);
=> Null pointer access: This expression of type Integer is null but requires auto-unboxing.

但是如果 null 设法作为参数传递(例如,如果参数之一是 null 属性),注释不会阻止它,导致运行时NullPointerException。如果您非常关心传递 null 值(您不应该这样做),则可以使用 Optional 优雅地处理其中一个参数为 null:[=22 的情况=]

public static Optional<Integer> add(Integer a, Integer b) {
    if (a == null || b == null)
        return Optional.empty();
    return Optional.of(a + b);
}

现在调用者有责任确定在无法计算值时该怎么做,另外一个好处是调用者现在意识到可能会发生这种情况。

what if I would have a method to which null can be passed (non-primitive) but from the name of the method it would be obvious that you can't pass null because you can't add something to null?

你不能相信名字。考虑

Integer add(Integer a, Integer b) {
    return a == null|| b == null ? null : a + b;
}

你可能会说,像这样的方法不会处理 null 但确实有这样的方法。

来自java.util.Objects

public static boolean equals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
}

public static boolean deepEquals(Object a, Object b) {
    if (a == b)
        return true;
    else if (a == null || b == null)
        return false;
    else
        return Arrays.deepEquals0(a, b);
}

最后,是否具有 null 值对实现很重要。

但在 没有实施的情况下 (或尚未实施),例如 API,必须在整个 API 中使用它们结合文档(即 javadoc)。

顺便说一句,你的第一个问题很糟糕,因为 int 不能为 null。在你澄清之后这个问题就没有意义了。