有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java@NonNull和@Nullable的正确用法是什么?

我对这些注释的正确使用感到困惑

安卓.support.annotation.NonNull;
安卓.support.annotation.Nullable;

文件中关于@NonNull的信息说:

Denotes that a parameter, field or method return value can never be null.

在参数的情况下,当没有任何东西阻止您传递null时,这意味着什么

例如,假设我有一个类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,安卓 studio告诉我setTitle的参数可能也应该标记为@Nullable(但这与我想要的相反)

如果我将setTitle方法的参数标记为@NonNull,我会得到一个警告,条件title == null总是false

在这种情况下,这些注释的正确用法是什么?如果@NonNull意味着一个参数可以永远是null,那么用它来表示不应该是null是错误的吗?如果是,是否有正确的方式表示


共 (4) 个答案

  1. # 1 楼答案

    如果将参数标记为@NonNull,则方法的用户需要执行null检查,因为@NonNull在运行时不会捕获NPE。例如,如果您有一个实用程序类,该类带有在执行前检查null的helper方法,那么您会将这些参数标记为@Nullable,因为从技术上讲,您可以传递null值,但可以安全地检查它

  2. # 2 楼答案

    关键是,此注释是某种契约,因此如果正确地注释了方法,则无需进行检查。Android Studio将检查您是否弄乱了它。您仍然可以忽略它,但这将导致编译器警告

    如果您忽略了无用的(按约定)安全检查,它将正确地抛出NullPointerException。但是开发人员收到了您的注释的警告

  3. # 3 楼答案

    @Nonnull@Nullable是声明性的。这是对其他软件开发人员的一个提示。您告诉他们,参数可以是空值,也可以不是空值

    如果您使用@Nonnull注释标记参数,您会告诉每个使用API的人,他们不应该在此处传递空值,否则他们必须处理结果(例如NullPointerException

    您可以使用它来声明,参数不应该为null,我认为这是一个有效的用例

  4. # 4 楼答案

    继续并将setTitle方法的参数标记为@NonNull

    这将确保编译器在某些代码调用setTitle时发出错误,其值可能为null。因此,编译器确保setTitle从不使用null调用。因此,您可以删除方法中的null检查,使“title==null总是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的表达式传递给setTitle时遇到错误Null type mismatch: required '@NonNull String' but the provided value is null(/inferred as @Nullable)。)

    顺便说一句:用@Nullable注释字段title的定义将使其更加明确title也可能包含null