Java-лучший способ обнаружить NPE во время компиляции, когда не разрешено использовать аннотации @NotNull или @Nullable
я использовал много @NotNull/@Nullable аннотации, позволяющие IDE помочь мне узнать потенциал NPE во время компиляции. Однако моя новая команда не позволяет использовать @NotNull/@Nullable аннотации, а также пользовательские аннотации, такие как разрешенные. В результате я стал гораздо чаще писать ошибки, вызванные NPE чем раньше.
я пробовал несколько решений:
- использовать
Optional<T>в java 8. Однако это не всегда хорошо. Это, как правило, не рекомендуется использоватьOptional<T>как тип полей или аргументов. Это также очень расстраивает, чтоOptional<T>сам экземпляр может бытьnull. Кроме того, сложно управлять потоками управления внутри лямбда-выражений при вызовеifPresent(obj->...)(проще в Java 9). И используя слишком многоOptional<T>s делает код немного многословен.(UPDATE: к сожалению,Optional<T>также запрещено использовать сейчас) - сделать IDE рассматривать каждый необъявленный экземпляр как
@Nullable. Это решение помогите мне выяснить некоторые потенциальные ошибки, однако IDE предложит мне проверить почти каждый вызов метода, что действительно раздражает, так как многие методы разработаны намеренно не возвращаяnull. - проверьте все вызовы методов. Это жизнеспособное решение, однако оно имеет серьезное влияние, что возможность быть
nullбудет передаваться везде через вызовы методов. При таких обстоятельствах каждый аргумент метода может бытьnull, и когда аргумент проверяется на nullity, метод обычно возвращаетnullнепрерывно. Наконец, каждый метод "заражен" возможностью полученияnullАргументы и возвращениеnull. - вызов
Objects.requireNonNull()чтобы предотвратить вышеупомянутую проблему. Это немного уменьшает боль проверкиnullвезде. Однако это не гарантирует, что вызывающий абонент не передастnullв случаях, когдаnullНе допускается. И один разnullпередано, время работыNPEthrown гораздо более вероятно, чтобы разрушить ваше приложение. - переключиться на Котлин. Конечно, это не допускается:)
есть ли другие предложения об обнаружении NPE во время компиляции (и сохранении моей работы)? я думаю, что решение этой проблемы может быть широко использован не только помогаете себе, так как не все команды позволяют использование @NotNull/@Nullable аннотации Optional<T>s.
6 ответов
не окончательный ответ, но несколько способов исследовать:
- инструменты findBug, PMD , Coverity ... довольно хороши в этом упражнении.
- Проверьте причину, по которой вы не можете использовать аннотацию в своей команде. Может быть, вы сможете заставить свою команду передумать? (На то может быть и веская причина.)
- в Eclipse IDE является reasonnably хорош в этом экзерсисе. Вы пробовали параметры в " Windows > настройки > Java > Компилятор > ошибки / предупреждения > нулевой анализ'?
- модульное тестирование. Рассмотрим ситуацию "не должно произойти" в нескольких тестовых случаях. Инструменты покрытия кода (например,JaCoCo) может быть полезным, как wel.
- оборонительное Программирование (простое утверждение "if", утверждения ...)
- смесь предыдущих элементов
надеюсь, что это помогает.
вы не сказали, какую IDE вы используете, но Eclipse и Intellij поддерживают внешние аннотации. С их помощью вы все равно можете аннотировать свой код локально и предоставить IDE нулевой анализ.
Я рекомендую проверить SonarLint, которая является очень хорошим инструментом для обнаружения всех видов ошибок и ошибок, в том числе NPE.
вы, вероятно, можете найти способ использовать Optional<T> это подходит для ваших случаев.
предположим, вы должны написать метод U doStuff(T param) и param дается вашему коду некоторой библиотекой от другого человека, и он может быть нулевым.
внутри тела метода doStuffможно сделать
return Optional.ofNullable(param)
.map(notNullParam -> doThing(notNullParam))
.orElse(null);
таким образом, вы уверены, что ваш Optionalсам по себе не null, люди все еще могут использовать ваш API с параметрами, которые являются null, и вы возвращаете null, когда это имеет смысл для их.
что вы должны сделать-это придумать хороший дизайн API и указать, какой из слоев разрешено возвращать null, а какой нет.
В общем, вы всегда должны пытаться вернуть что - то другое, а не пустую коллекцию, объект, представляющий not-found.
поэтому вы должны проверить наличие нулей вручную, где возврат может иметь смысл быть нулевым. В противном случае просто соберите, чтобы не возвращать null и просто не проверять.
вы также можете ввести некоторые методы утилиты для проверки нулевых / пустых коллекций:
Check.isEmpty() вернет true, если коллекция равна null или не равна null, но пуста и так далее...
вы также можете использовать нулевой объект шаблона
Я могу связать вашу проблему с моими вариантами использования. В этих случаях не стесняйтесь предлагать инструменты покрытия кода.
- JaCoCo очень удобно. Если вы используете IntelliJ, встроенное покрытие кода Jacoco/IJ ясно дает вам нарушения и возможный NPE
- тесты для поддержки Вашего домена мудрые ненулевые сценарии объектов
ведь NPE до сих пор дизайн, основанный/программист на основе вина. Держите код хорошо протестирован и правильных проверок, чтобы избежать NPE и бросить пользовательские исключения или IllegalArgumentException Если ваш сервис предполагает допустимое значение.