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

时间:2016-07-30 16:10:27

标签: java intellij-idea annotations nullable notnull

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

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

澄清:

现在我知道一个人不能将null传递给原始变量但是我想问一下,如果我有一个方法(带有非原始参数),null可以是什么通过但是从方法的名称可以明显看出你不能通过null,因为例如,你不能向null添加内容?

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

3 个答案:

答案 0 :(得分:4)

在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值(您不应该这样做),那么当其中一个参数为null时,您可以使用Optional来优雅地处理这种情况:

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

现在调用者有责任确定如果无法计算值,该怎么办,并且调用者现在意识到可能会发生这种情况的额外好处。

答案 1 :(得分:1)

  

如果我有一个可以传递null的方法(非原始),但是从方法的名称很明显你不能传递null,因为你不能添加一些东西到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);
}

答案 2 :(得分:0)

最后,对于具有null - 值的实现非常重要。

但是在一个你没有没有实现(或者还没有)的情况下,它们必须在整个API中与文档(javadoc ie)结合使用。

顺便说一下,你的第一个问题很糟糕,因为int无法保持为空。澄清之后,这个问题就再没有意义了。