@NonNull 和@Nullable 的正确用法是什么?
What are the correct uses of @NonNull and @Nullable?
我对这些注释的正确使用感到困惑。
android.support.annotation.NonNull;
android.support.annotation.Nullable;
@NonNull
文档中的信息说:
Denotes that a parameter, field or method return value can never be null.
在参数的情况下,当没有什么可以阻止您传递时,这意味着什么 null
?
例如,假设我有一个 class MyObject
并且实例可能有也可能没有标题。
public final class MyObject {
private String title = null;
public void setTitle(String title) {
if (title == null)
throw new NullPointerException();
this.title = title;
}
public void clearTitle() {
title = null;
}
}
这里我使用null
来表示没有标题,但这是一个实现细节,所以我不想要一个单一的方法来设置和清除标题。
如果我将字段 title
标记为 @Nullable
,android studio 告诉我 setTitle
的参数可能也应该标记为 @Nullable
(但这与我想要的相反)。
如果我将 setTitle
方法的参数标记为 @NonNull
我会收到一条警告,指出条件 title == null
始终是 false
.
在这种情况下,这些注释的正确用法是什么?如果 @NonNull
意味着参数 can 永远不会 null
使用它来表示 should not be null
是错误的吗=13=]?如果是,是否有正确的表示方式?
@Nonnull
和 @Nullable
是声明性的。这是对其他软件开发人员的提示。你告诉他们,参数可以是空值,也可以不是。
如果你用 @Nonnull
注释标记一个参数,你告诉每个使用你的 API 的人他们不应该在这里传递空值,否则他们必须处理后果(例如NullPointerException
).
你可以用它来声明,参数不应该为空,在我看来这是一个有效的用例。
关键是这个注解是某种契约,所以如果你正确地注解了你的方法,你就不需要进行检查。 Android Studio 会检查您是否弄乱了它。您仍然可以忽略它,但这会导致编译器警告。
如果您忽略无用的(根据合同)安全检查,它将正确地抛出 nullpointerexceptions。但是开发人员收到了您的注释警告。
继续将 setTitle
方法的参数标记为 @NonNull
。
这将确保编译器在某些代码调用 setTitle
且值 可能为 null 时发出错误。所以编译器确保 setTitle
是 never 用 null
调用。因此,您可以删除方法中的 null
检查,使 'title == null is always false' 警告消失。
即您的代码将如下所示:
public final class MyObject {
private String title = null;
public void setTitle(@NonNull String title) {
this.title = title;
}
public void clearTitle() {
title = null;
}
}
(注意:我没有使用 Android Studio,但我猜它的行为类似于 Eclipse。在 Eclipse 中,当我尝试将 null 或可能为 null 的表达式传递给设置标题。)
顺便说一句:还用 @Nullable
注释字段 title
的定义将使它更明确 title
也可能包含 null
值。
如果您标记参数@NonNull,那么您的方法的用户需要进行空检查,因为@NonNull 不会在运行时捕获 NPE。因此,例如,如果您有一个实用程序 class,其辅助方法会在执行前检查 null,那么您会将这些参数标记为 @Nullable,因为从技术上讲,您可以传递 null 值,但正在安全地检查它。
我对这些注释的正确使用感到困惑。
android.support.annotation.NonNull;
android.support.annotation.Nullable;
@NonNull
文档中的信息说:
Denotes that a parameter, field or method return value can never be null.
在参数的情况下,当没有什么可以阻止您传递时,这意味着什么 null
?
例如,假设我有一个 class MyObject
并且实例可能有也可能没有标题。
public final class MyObject {
private String title = null;
public void setTitle(String title) {
if (title == null)
throw new NullPointerException();
this.title = title;
}
public void clearTitle() {
title = null;
}
}
这里我使用null
来表示没有标题,但这是一个实现细节,所以我不想要一个单一的方法来设置和清除标题。
如果我将字段 title
标记为 @Nullable
,android studio 告诉我 setTitle
的参数可能也应该标记为 @Nullable
(但这与我想要的相反)。
如果我将 setTitle
方法的参数标记为 @NonNull
我会收到一条警告,指出条件 title == null
始终是 false
.
在这种情况下,这些注释的正确用法是什么?如果 @NonNull
意味着参数 can 永远不会 null
使用它来表示 should not be null
是错误的吗=13=]?如果是,是否有正确的表示方式?
@Nonnull
和 @Nullable
是声明性的。这是对其他软件开发人员的提示。你告诉他们,参数可以是空值,也可以不是。
如果你用 @Nonnull
注释标记一个参数,你告诉每个使用你的 API 的人他们不应该在这里传递空值,否则他们必须处理后果(例如NullPointerException
).
你可以用它来声明,参数不应该为空,在我看来这是一个有效的用例。
关键是这个注解是某种契约,所以如果你正确地注解了你的方法,你就不需要进行检查。 Android Studio 会检查您是否弄乱了它。您仍然可以忽略它,但这会导致编译器警告。
如果您忽略无用的(根据合同)安全检查,它将正确地抛出 nullpointerexceptions。但是开发人员收到了您的注释警告。
继续将 setTitle
方法的参数标记为 @NonNull
。
这将确保编译器在某些代码调用 setTitle
且值 可能为 null 时发出错误。所以编译器确保 setTitle
是 never 用 null
调用。因此,您可以删除方法中的 null
检查,使 'title == null is always false' 警告消失。
即您的代码将如下所示:
public final class MyObject {
private String title = null;
public void setTitle(@NonNull String title) {
this.title = title;
}
public void clearTitle() {
title = null;
}
}
(注意:我没有使用 Android Studio,但我猜它的行为类似于 Eclipse。在 Eclipse 中,当我尝试将 null 或可能为 null 的表达式传递给设置标题。)
顺便说一句:还用 @Nullable
注释字段 title
的定义将使它更明确 title
也可能包含 null
值。
如果您标记参数@NonNull,那么您的方法的用户需要进行空检查,因为@NonNull 不会在运行时捕获 NPE。因此,例如,如果您有一个实用程序 class,其辅助方法会在执行前检查 null,那么您会将这些参数标记为 @Nullable,因为从技术上讲,您可以传递 null 值,但正在安全地检查它。