Android Studio错误的含义:未注释的参数覆盖了@NonNull参数。

114

我正在尝试使用Android Studio。在创建新项目并向create MyActivity类中添加默认的onSaveInstanceState方法后,在尝试将代码提交到Git时,我收到了一个奇怪的错误,我不理解。代码如下:

我收到的错误是:

enter image description here

如果我尝试更改方法签名为protected void onSaveInstanceState(@NotNull Bundle outState),那么IDE告诉我无法解析符号NotNull

我需要做什么来摆脱这个警告?

4个回答

136

这是一个注解,但正确的名称是NonNull

protected void onSaveInstanceState(@NonNull Bundle outState)

(而且)

import android.support.annotation.NonNull;

目的是允许编译器在违反某些假设时发出警告(例如方法的参数应始终具有值,就像这个特定情况一样,尽管还有其他情况)。根据支持注释文档:

@NonNull注释可用于指示给定参数不能为空。

如果已知局部变量为空(例如因为先前的代码检查了它是否为空),并且您将其作为参数传递到标记为@NonNull的方法中,IDE将警告您存在潜在崩溃。

它们是静态分析工具。运行时行为不会改变。


在这种情况下,特定警告是您正在覆盖的原始方法(在Activity中)在outState参数上有一个@NonNull注释,但是您没有在重写方法中包含它。只需添加它即可解决问题,即:

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}

6
它的目的是什么? - IgorGanapolsky
2
@IgorGanapolsky 抱歉,我没有提到这一点,因为我认为问题只涉及“NotNull”/“NonNull”的区别。已相应调整答案。 - matiash
2
换句话说,在我看来,这个注解可以在函数内部消除对空值的检查,并且使代码更快。 - John Pang
1
@JohnPang你"可以"这样做,但是由于注释所暗示的限制无法得到保证地执行,这可能不是一个好主意。 - matiash
import android.support.annotation.NonNull; 寻找这个东西已经两个小时了... 没有人提到如何导入NonNull.. 因此点赞 - Shirish Herwade
显示剩余2条评论

17

最近在Android支持库中新增了一些有用的支持注解。它们的主要作用是为各种方法和参数的属性添加注释以帮助捕获错误。例如,如果您向标记有NotNull注解的参数传递null值,则会收到警告。

您可以通过在Gradle中添加以下依赖项将这些注解添加到您的项目中:

dependencies {
    compile 'com.android.support:support-annotations:20.0.0'
}

你收到这个警告是因为Bundle参数被标记了@NotNull注解,而重写方法时该注解被隐藏了。正确的做法是在重写的方法参数中也添加该注解。

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}

这个答案实际上解释了消除警告的价值。这是对所发布问题(警告的含义)的有趣回答。谢谢。但是...这里缺少的是如何修复它们在消除警告后遇到的错误。即:import androidx.annotation.NonNull。 - steve

9
除其他答案外,@NonNull(以及它的对手,@Nullable)注解会注释字段、参数或方法返回类型。IntelliJ和因此Android Studio可以在编译时警告您可能的NullPointerException
这里最好举一个例子:
@NonNull private String myString = "Hello";

@Nullable private String myOtherString = null;

@NonNull 
public Object doStuff() {
    System.out.println(myString.length); // No warning
    System.out.println(doSomething(myString).length); // Warning, the result might be null.

    doSomething(myOtherString); // Warning, myOtherString might be null.

    return myOtherString; // Warning, myOtherString might be null.
}

@Nullable
private String doSomething(@NonNull String a) {
    return a.length > 1 ? null : a; // No warning
}

这些注释不会改变运行时行为(虽然我已经进行了实验),但它们作为预防错误的工具。

请注意,您收到的消息不是错误,而只是一个警告,如果您选择忽略它是安全的。另一种选择是像Android Studio建议的那样自己对参数进行注释:

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}

0

旧问题和已发布的答案包含了很好的内容。但是,没有一个命中要害。

你提出了两个问题。

首先,你询问警告“未注释参数覆盖@NonNull参数”的含义。这就是我来到这里的原因(9年后)。这个警告意味着什么?它暗示了什么?添加注释的价值是什么?根据@LukaCiko的说法,注释在覆盖时会丢失。谢谢@LukaCiko。因此,如果您希望被覆盖的方法的参数具有与超类相同的注释,则需要包括注释。

其次,当您添加注释时,您会收到编译器错误。为了修复,导入androidx.annotation.NonNull(可能当时有不同的命名空间)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接