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
передано, время работыNPE
thrown гораздо более вероятно, чтобы разрушить ваше приложение. - переключиться на Котлин. Конечно, это не допускается:)
есть ли другие предложения об обнаружении 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
Если ваш сервис предполагает допустимое значение.