Значение ошибки Android Studio: параметр без аннотации переопределяет параметр @NonNull

104

Я пробую Android Studio. После создания нового проекта и добавления onSaveInstanceStateметода по умолчанию в класс create MyActivity, когда я пытаюсь зафиксировать код в Git, я получаю странную ошибку, которую я не понимаю. Код такой:

Я получаю такую ​​ошибку:

введите описание изображения здесь

Если я попытаюсь изменить сигнатуру метода на protected void onSaveInstanceState(@NotNull Bundle outState), тогда IDE сообщит мне, что не может разрешить символ NotNull.

Что мне нужно сделать, чтобы избавиться от предупреждения?

Мономо
источник

Ответы:

124

Это аннотация, но правильное название NonNull:

protected void onSaveInstanceState(@NonNull Bundle outState)

(А также)

import android.support.annotation.NonNull;

Цель состоит в том, чтобы позволить компилятору предупреждать, когда определенные предположения нарушаются (например, параметр метода, который всегда должен иметь значение, как в этом конкретном случае, хотя есть и другие). Из документации Support Annotations :

@NonNullАннотации можно использовать , чтобы указать , что данный параметр не может быть пустым.

Если известно, что локальная переменная имеет значение NULL (например, из-за того, что какой-то более ранний код проверял, была ли она нулевой), и вы передаете это в качестве параметра методу, где этот параметр помечен как @NonNull, IDE предупредит вас, что у вас потенциальная авария.

Это инструменты статического анализа. Поведение во время выполнения не изменяется.


В этом случае особое предупреждение заключается в том, что исходный метод, который вы переопределяете (в Activity), имеет @NonNullаннотацию к outStateпараметру, но вы не включили ее в метод переопределения. Простое добавление должно решить проблему, т.е.

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
матиаш
источник
5
Какая у этого цель?
Игорь Ганапольский
2
@IgorGanapolsky Извините, я не упомянул об этом, потому что я предположил, что вопрос был только о разнице NotNull/ NonNull. Скорректированный ответ соответственно.
matiash
2
Другими словами, IMHO, эта аннотация может устранить необходимость проверки нуля внутри функции и иметь более быстрый код.
Джон Панг,
1
@JohnPang Вы могли бы , но поскольку ограничение, подразумеваемое аннотацией, не гарантируется, что на самом деле будет соблюдаться, это может быть не очень хорошей идеей.
matiash
import android.support.annotation.NonNull; искал эту штуку в течение 2 часов ... ни один не упомянул, как импортировать NonNull ... отсюда и голосование
Шириш Хервэйд
15

В библиотеку поддержки Android недавно был добавлен ряд полезных аннотаций поддержки. Их основная роль - аннотировать свойства различных методов и параметров, чтобы помочь отловить ошибки. Например, если вы передадите nullзначение параметру, отмеченному NotNullаннотацией, вы получите предупреждение.

Аннотации можно добавить в ваш проект с помощью Gradle, добавив следующую зависимость:

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

Вы получаете предупреждение, потому что Bundleпараметр отмечен @NotNullаннотацией и при переопределении метода аннотация становится скрытой. Правильнее всего будет добавить аннотацию к параметру переопределенного метода.

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
}
ЛукаСико
источник
9

В дополнение к другим ответам аннотация @NonNull(и ее противник @Nullable) аннотирует тип возвращаемого поля, параметра или метода. IntelliJ и, следовательно, Android Studio могут предупредить вас о возможных NullPointerExceptions во время компиляции.

Пример лучше всего здесь:

@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);
}
Nhaarman
источник