Significato dell'errore di Android Studio: il parametro non annotato sostituisce il parametro @NonNull


104

Sto provando Android Studio. Dopo aver creato un nuovo progetto e aggiunto un onSaveInstanceStatemetodo predefinito alla classe create MyActivity, quando provo a eseguire il commit del codice su Git, ottengo uno strano errore che non capisco. Il codice è questo:

L'errore che ottengo è questo:

inserisci qui la descrizione dell'immagine

Se provo a cambiare la firma del metodo in protected void onSaveInstanceState(@NotNull Bundle outState), l'IDE mi dice che non può risolvere il simbolo NotNull.

Cosa devo fare per eliminare l'avviso?

Risposte:


124

È un'annotazione, ma il nome corretto è NonNull:

protected void onSaveInstanceState(@NonNull Bundle outState)

(E anche)

import android.support.annotation.NonNull;

Lo scopo è quello di consentire al compilatore di avvisare quando vengono violate determinate ipotesi (come un parametro di un metodo che dovrebbe sempre avere un valore, come in questo caso particolare, sebbene ce ne siano altri). Dalla documentazione delle annotazioni di supporto :

L' @NonNullannotazione può essere utilizzata per indicare che un dato parametro non può essere nullo.

Se una variabile locale è nota per essere nulla (ad esempio perché un codice precedente ha verificato se era nulla) e la si passa come parametro a un metodo in cui quel parametro è contrassegnato come @NonNull, l'IDE ti avviserà che hai un potenziale incidente.

Sono strumenti per l'analisi statica. Il comportamento in fase di esecuzione non viene affatto alterato.


In questo caso, l'avviso particolare è che il metodo originale che stai sovrascrivendo (in Activity) ha @NonNullun'annotazione sul outStateparametro, ma non l'hai inclusa nel metodo di sovrascrittura. Basta aggiungerlo per risolvere il problema, ad es

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

5
Qual è lo scopo?
IgorGanapolsky

2
@IgorGanapolsky Scusa, non l'avevo detto perché pensavo che la domanda riguardasse solo la NotNull/ NonNulldifferenza. Risposta adattata di conseguenza.
matiash

2
In altre parole, IMHO, questa annotazione può rimuovere il necessario del controllo null all'interno di una funzione e avere un codice più veloce.
John Pang

1
@JohnPang Si potrebbe , ma dal momento che la restrizione implicita l'annotazione non è garantito per essere effettivamente applicata, potrebbe non essere una buona idea.
matiash

import android.support.annotation.NonNull; cercando questa cosa per 2 ore ... nessuno ha menzionato come importare NonNull .. quindi
voto positivo

15

Recentemente sono state aggiunte alcune utili annotazioni di supporto nella libreria di supporto Android. Il loro ruolo principale è annotare le proprietà di vari metodi e parametri per aiutare a individuare i bug. Ad esempio, se si passa il nullvalore a un parametro contrassegnato conNotNull annotazione, verrà visualizzato un avviso.

Le annotazioni possono essere aggiunte al tuo progetto con Gradle aggiungendo la seguente dipendenza:

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

Ricevi l'avviso perché il Bundleparametro è contrassegnato con l' @NotNullannotazione e sovrascrivendo il metodo l'annotazione viene nascosta. La cosa giusta da fare è aggiungere l'annotazione anche al parametro del metodo sovrascritto.

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

9

Oltre alle altre risposte, l' annotazione @NonNull(e il suo avversario @Nullable) annota un campo, un parametro o un tipo di ritorno del metodo. IntelliJ e quindi Android Studio possono avvisarti di eventuali messaggi di NullPointerExceptionposta elettronica in fase di compilazione.

Un esempio è il migliore qui:

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

Queste annotazioni non alterano il comportamento in fase di esecuzione (sebbene io abbia sperimentato questo), ma servono come strumento per prevenire i bug.

Nota che il messaggio che hai ricevuto non era un errore, ma solo un avviso, che è sicuro ignorare, se lo desideri. L'alternativa è annotare anche tu il parametro, come suggerisce Android Studio:

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.