113

I'm trying out Android Studio. Upon creating a new project and adding a default onSaveInstanceState method to the create MyActivity class, when I try to commit the code to Git, I get a strange error I don't understand. The code is this:

The error I get is this:

enter image description here

If I try to change the method signature to protected void onSaveInstanceState(@NotNull Bundle outState), then the IDE tells me it can't resolve the symbol NotNull.

What do I need to do to get rid of the warning?

hofs
  • 469
  • 4
  • 12
Monomo
  • 1,193
  • 2
  • 7
  • 5

4 Answers4

135

It's an annotation, but the correct name is NonNull:

protected void onSaveInstanceState(@NonNull Bundle outState)

(And also)

import android.support.annotation.NonNull;

The purpose is to allow the compiler to warn when certain assumptions are being violated (such as a parameter of a method that should always have a value, as in this particular case, although there are others). From the Support Annotations documentation:

The @NonNull annotation can be used to indicate that a given parameter can not be null.

If a local variable is known to be null (for example because some earlier code checked whether it was null), and you pass that as a parameter to a method where that parameter is marked as @NonNull, the IDE will warn you that you have a potential crash.

They are tools for static analysis. Runtime behavior is not altered at all.


In this case, the particular warning is that the original method you're overriding (in Activity) has a @NonNull annotation on the outState parameter, but you did not include it in the overriding method. Just adding it should fix the issue, i.e.

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
matiash
  • 54,791
  • 16
  • 125
  • 154
  • 6
    What is the purpose of it? – IgorGanapolsky Sep 10 '14 at 17:36
  • 2
    @IgorGanapolsky Sorry, hadn't mentioned that because I assumed the question was only about the `NotNull`/`NonNull` difference. Adjusted answer accordingly. – matiash Nov 19 '14 at 16:38
  • 2
    In other word, IMHO, this annotation can remove the necessary of null-checking inside a function, and have a faster code. – John Pang Mar 27 '15 at 20:07
  • 1
    @JohnPang You _could_, but since the restriction implied by the annotation isn't guaranteed to be actually enforced, it might not be a good idea. – matiash Mar 27 '15 at 20:16
  • import android.support.annotation.NonNull; looking for this thing for 2 hours... not one mentioned how to import NonNull.. hence upvote – Shirish Herwade Aug 11 '16 at 10:18
  • Reported the bug to JetBrains [@NotNull should be @NonNull](https://intellij-support.jetbrains.com/hc/en-us/community/posts/360000214479-External-annotations-Not-annotated-parameter-overrides-NotNull-parameter?page=1#community_comment_360000106199) – JMess Aug 21 '18 at 18:19
  • The question is about the warning message, not the annotation. The discussion of the annotation is off target. The bit about "warning is that the original method you're overriding has a @NonNull but you did not include it in the overriding method." is correct; even obvious and OP clearly gets that. My question and probably theirs is: What's the value of adding the annotation? IOW why is this a warning? – steve May 14 '23 at 15:27
17

A number of useful support annotations were recently added in the Android support library. Their primary role is to annotate properties of various methods and parameters to help catch bugs. For example, if you pass null value to a parameter that is marked with the NotNull annotation you will get a warning.

The annotations can be added to your project with Gradle by adding the following dependency:

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

You are getting the warning because the Bundle parameter is marked with the @NotNull annotation and by overriding the method the annotation gets hidden. The right thing to do is to add the annotation to the overriden method's parameter as well.

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
LukaCiko
  • 4,437
  • 2
  • 26
  • 30
  • This answer actually explains the _value_ of eliminating the warning. That's the interesting answer to the posted question (meaning of the warning). Thanks. But... the thing missing here is how to fix the error they get (after eliminating the warning). That's: import androidx.annotation.NonNull – steve May 14 '23 at 15:25
9

In addition to the other answers, the @NonNull (and it's opponent, @Nullable) annotation annotates a field, parameter or method return type. IntelliJ and thus Android Studio can warn you for possible NullPointerExceptions at compile time.

An example is best here:

@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
}

These annotations do not alter runtime behavior (although I have experimented with this), but serve as a tool for preventing bugs.

Note that the message you received was not an error, but just a warning, which is safe to ignore, if you choose to. The alternative is to annotate the parameter yourself as well, as Android Studio suggests:

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
nhaarman
  • 98,571
  • 55
  • 246
  • 278
0

Old question and the already posted answers contain good stuff. But, none hit the nail on the head.

You ask two questions.

First, you ask about the meaning of the warning "Not annotated parameter overrides @NonNull parameter". This is what brought me here (9 years later). What does the warning mean? What does it imply? What's the value of adding the annotation? According to @LukaCiko, the annotation is lost in the override. Thank you @LukaCiko. So, if you want the overridden method's parameter to have same annotation as the superclass, then you want to include the annotation.

Second, when you added the annotation, you got a compiler error. To fix, import androidx.annotation.NonNull (probably had a different namespace back then)

steve
  • 1,021
  • 1
  • 14
  • 29