Android @NonNull полезность

После нескольких чтений и вопросов как этот мне было интересно, есть ли смысл использовать @NonNull Андроид аннотации для Android.

Я вижу небольшое предупреждение от Android Studio, если попытаюсь вызвать метод с параметром null, который аннотируется как @NonNull. Просто предупреждение?

Как насчет модульного тестирования? Должен ли я протестировать метод с нулевым параметром? Если я это сделаю... я получу NullPointerException, и мой тест завершится неудачно.

Скажем, мы два разработчика. Один из них работает над API и один тестирует API во всех манерах. Как второй разработчик, я обязан проверить все, чтобы API был пуленепробиваемым. То, что весь пункт Unit Testing, правильно?

Итак, тогда... что точка первого разработчика, использующая @NonNull?

Если кто-то другой должен был использовать этот API с нулевым параметром... тогда API будет бросать NPE. Затем он подумал: "Ург, этот API отстой... NPE!" и он будет прав. Этот непослушный разработчик, не проверяющий, имеет ли параметр, который он отправил, null или нет, должен сталкиваться с IllegalArgumentException, потому что это его ошибка не в том, что у API!

Я не прав?

Я думал, что эти аннотации заставят компилятор показать такие ошибки, как attempting to call methodName(@NonNull Object object) with null parameter.

Обновление 1

Хорошо, спасибо всем за ваши комментарии. Я хотел бы высказать, если возможно, вопрос "проблема", с которой я столкнулся. Абстрактным образом.

Я пишу некоторый код (API, Библиотека, класс, любой) с закрытым внутренним кодом, обернутым общедоступными методами, предоставляющими функции.

Предположим, что эти общедоступные методы будут использоваться кем-то другим (включая меня). Некоторые из них принимают аргументы, которые никогда не должны быть null, иначе все ад сломается.

Считывая ваши комментарии, я столкнулся со следующими вариантами:

  • Продолжайте использовать контракты/аннотации (@NonNull), поддерживаемые документацией Java, предусматривающие parameter must not be null. Не проверяйте нулевые параметры (иначе IDE будет предупреждать меня) и, как-то, молитесь, чтобы я никогда не получил нулевой параметр;
  • То же, что и выше, но применяйте нулевую проверку (даже если IDE будет предупреждать, что condition will always be false) и бросать IllegalArgumentException вместо того, чтобы вызывать NPE в случае, если я получаю нулевой параметр;
  • Остановить использование контрактов/аннотаций, использовать Java Doc для предупреждения других разработчиков и добавить ручную проверку для всех параметров.

Наконец, для модульного тестирования... Я знаю, что я не могу иметь пуленепробиваемый код, но мне нравится "обезвреживать" мой код как можно больше, чтобы предотвратить неожиданное поведение из моего кода, а также для проверки процесса (который, как я полагаю, лежит в основе Unit Testing) -

Ответ 1

Его основная цель - информационная для ваших коллег. Один человек никогда не является единственным программистом большого проекта. Использование NotNull говорит другим программистам, что контракт функции означает, что вы никогда не сможете отправить ему нуль, поэтому они этого не делают. В противном случае я могу сделать логическое предположение, что вызов setFoo (null) очистит Foo, тогда как API не может обрабатывать не иметь Foo.

Ответ 2

Ваш подход №2 на мой взгляд - правильный способ сделать это для API/библиотеки. Используйте аннотацию для статического анализа, чтобы предотвратить попытки компиляции при вызове метода с нулевым значением и использовать нулевую проверку во время выполнения, чтобы дать полезное исключение (а также не быстро/защитить от непредвиденных событий от вашего кода), если значение null объект передается. Используйте директиву noinspection ConstantConditions перед нулевой проверкой, чтобы сообщить IDE подавить предупреждение (поскольку вы проверяете нуль по уважительной причине).

Случайный NPE указывает, что автор библиотеки /api, возможно, что-то пропустил и имеет ошибку, которая не обрабатывается в их коде.

An IllegalArgumentException (или NPE с описанием проблемы - какое исключение для использования в этом случае является аргументом, основанным на мнении) указывает, что вызывающий ошибся в способе, которым они вызвали метод.

В конечном итоге, будь то проверять значение null после того, как вы уже аннотировали @NonNull, он будет основан на мнениях и зависит от ситуации.

Ответ 3

Возможно, слишком поздно комментировать, но лучше, чем никогда:)

Существует Traute плагин javac, который вставляет нулевые проверки в сгенерированный байт-код на основе аннотаций параметров метода.

Вот пример проекта Android, который иллюстрирует это.