Significado do erro do Android Studio: o parâmetro não anotado substitui o parâmetro @NonNull

104

Estou testando o Android Studio. Ao criar um novo projeto e adicionar um onSaveInstanceStatemétodo padrão à classe create MyActivity, quando tento enviar o código para o Git, recebo um erro estranho que não entendo. O código é este:

O erro que recebo é este:

insira a descrição da imagem aqui

Se eu tentar alterar a assinatura do método para protected void onSaveInstanceState(@NotNull Bundle outState), o IDE me diz que não pode resolver o símbolo NotNull.

O que preciso fazer para me livrar do aviso?

Monomo
fonte

Respostas:

124

É uma anotação, mas o nome correto é NonNull:

protected void onSaveInstanceState(@NonNull Bundle outState)

(E também)

import android.support.annotation.NonNull;

O objetivo é permitir que o compilador avise quando certas suposições estão sendo violadas (como um parâmetro de um método que deve sempre ter um valor, como neste caso particular, embora existam outros). Na documentação do Support Annotations :

A @NonNullanotação pode ser usada para indicar que um determinado parâmetro não pode ser nulo.

Se uma variável local é conhecida como nula (por exemplo, porque algum código anterior verificou se ela era nula), e você passa isso como um parâmetro para um método onde esse parâmetro está marcado como @NonNull, o IDE irá avisá-lo que você um acidente potencial.

Eles são ferramentas para análise estática. O comportamento do tempo de execução não é alterado de forma alguma.


Nesse caso, o aviso específico é que o método original que você está substituindo (in Activity) tem uma @NonNullanotação no outStateparâmetro, mas você não a incluiu no método de substituição. Apenas adicioná-lo deve resolver o problema, ou seja,

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
matiash
fonte
5
Qual é o propósito disso?
IgorGanapolsky
2
@IgorGanapolsky Desculpe, não mencionei isso porque presumi que a pergunta era apenas sobre a diferença NotNull/ NonNull. Resposta ajustada em conformidade.
matiash de
2
Em outras palavras, IMHO, essa anotação pode remover a verificação de nulos necessária dentro de uma função e ter um código mais rápido.
John Pang
1
@JohnPang Você poderia , mas como a restrição implícita na anotação não tem garantia de ser realmente aplicada, pode não ser uma boa ideia.
matiash
import android.support.annotation.NonNull; procurando por isso por 2 horas ... ninguém mencionou como importar NonNull .. portanto, upvote
Shirish Herwade
15

Uma série de anotações de suporte úteis foram adicionadas recentemente à biblioteca de suporte do Android. Sua função principal é anotar propriedades de vários métodos e parâmetros para ajudar a detectar bugs. Por exemplo, se você passar o nullvalor para um parâmetro que está marcado com a NotNullanotação, você receberá um aviso.

As anotações podem ser adicionadas ao seu projeto com Gradle adicionando a seguinte dependência:

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

Você está recebendo o aviso porque o Bundleparâmetro está marcado com a @NotNullanotação e, ao substituir o método, a anotação fica oculta. A coisa certa a fazer é adicionar a anotação ao parâmetro do método sobrescrito também.

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

Além das outras respostas, a anotação @NonNull(e seu oponente @Nullable) anota um tipo de retorno de campo, parâmetro ou método. O IntelliJ e, portanto, o Android Studio podem avisá-lo sobre possíveis NullPointerExceptions no momento da compilação.

Um exemplo é melhor aqui:

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

Essas anotações não alteram o comportamento do tempo de execução (embora eu tenha feito experiências com isso), mas servem como uma ferramenta para prevenir bugs.

Observe que a mensagem que você recebeu não foi um erro, mas apenas um aviso, que pode ser ignorado com segurança, se você quiser. A alternativa é anotar o parâmetro você mesmo também, como o Android Studio sugere:

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