Significado del error de Android Studio: el parámetro no anotado anula el parámetro @NonNull

104

Estoy probando Android Studio. Al crear un nuevo proyecto y agregar un onSaveInstanceStatemétodo predeterminado a la clase create MyActivity, cuando intento enviar el código a Git, aparece un error extraño que no entiendo. El código es este:

El error que obtengo es este:

ingrese la descripción de la imagen aquí

Si trato de cambiar la firma del método a protected void onSaveInstanceState(@NotNull Bundle outState), entonces el IDE me dice que no puede resolver el símbolo NotNull.

¿Qué debo hacer para eliminar la advertencia?

Monomo
fuente

Respuestas:

124

Es una anotación, pero el nombre correcto es NonNull:

protected void onSaveInstanceState(@NonNull Bundle outState)

(Y también)

import android.support.annotation.NonNull;

El propósito es permitir que el compilador advierta cuando se están violando ciertos supuestos (como un parámetro de un método que siempre debe tener un valor, como en este caso particular, aunque hay otros). De la documentación de Anotaciones de soporte :

La @NonNullanotación se puede utilizar para indicar que un parámetro determinado no puede ser nulo.

Si se sabe que una variable local es nula (por ejemplo, porque algún código anterior verificó si era nula), y lo pasa como parámetro a un método donde ese parámetro está marcado como @NonNull, el IDE le advertirá que tiene un posible accidente.

Son herramientas de análisis estático. El comportamiento en tiempo de ejecución no se modifica en absoluto.


En este caso, la advertencia particular es que el método original que está anulando (en Activity) tiene una @NonNullanotación en el outStateparámetro, pero no lo incluyó en el método de anulación. Solo agregarlo debería solucionar el problema, es decir

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
matiash
fuente
5
¿Cuál es el propósito de esto?
IgorGanapolsky
2
@IgorGanapolsky Lo siento, no había mencionado eso porque asumí que la pregunta era solo sobre la diferencia NotNull/ NonNull. Respuesta ajustada en consecuencia.
Matiash
2
En otras palabras, en mi humilde opinión, esta anotación puede eliminar lo necesario de la verificación de nulos dentro de una función y tener un código más rápido.
John Pang
1
@JohnPang Podría , pero dado que la restricción implícita en la anotación no se garantiza que se aplique realmente, puede que no sea una buena idea.
matiash
importar android.support.annotation.NonNull; buscando esto durante 2 horas ... nadie mencionó cómo importar NonNull ... por lo tanto, upvote
Shirish Herwade
15

Recientemente, se agregaron varias anotaciones de soporte útiles en la biblioteca de soporte de Android. Su función principal es anotar las propiedades de varios métodos y parámetros para ayudar a detectar errores. Por ejemplo, si pasa un nullvalor a un parámetro que está marcado con la NotNullanotación, recibirá una advertencia.

Las anotaciones se pueden agregar a su proyecto con Gradle agregando la siguiente dependencia:

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

Recibirá la advertencia porque el Bundleparámetro está marcado con la @NotNullanotación y, al anular el método, la anotación se oculta. Lo correcto es agregar la anotación al parámetro del método anulado también.

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

Además de las otras respuestas, la anotación @NonNull(y su oponente @Nullable) anota un tipo de retorno de campo, parámetro o método. IntelliJ y, por lo tanto, Android Studio pueden advertirle sobre posibles NullPointerExceptioncorreos electrónicos en tiempo de compilación.

Un ejemplo es mejor aquí:

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

Estas anotaciones no alteran el comportamiento en tiempo de ejecución (aunque he experimentado con esto), pero sirven como una herramienta para prevenir errores.

Tenga en cuenta que el mensaje que recibió no fue un error, sino solo una advertencia, que es seguro ignorar, si así lo desea. La alternativa es anotar el parámetro usted mismo también, como sugiere Android Studio:

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