我们应该始终使用@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。在你澄清之后这个问题就没有意义了。
我们是否应该始终在方法参数中使用 @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。在你澄清之后这个问题就没有意义了。