Перехват исключений нулевого указателя - PullRequest
14 голосов
/ 23 января 2012

Я задаю этот вопрос о Java, но я думаю, что он применим ко всем языкам.

Рассмотрим,

if(myVariable==null){
       doSomethingAboutIt();
}
else carryOn(myVariable);

и

try{
     carryOn(MyVariable);
}catch(NullPointerException e ){
      doSOmethingAboutIt();}

Являются ли оба этих кодовых блока по существу одинаковыми? Есть ли причина выбирать второй подход? Конечно, было бы лучше, если бы myVariable никогда не был нулевым, но, похоже, лучший способ проверить это - сделать простое выражение if.

Ответы [ 5 ]

10 голосов
/ 23 января 2012

С моей позиции, я не решаюсь считать эти два кодовых блока эквивалентными по своему намерению. Конечно, они проходят ту же обработку ошибок, но это решение разработчика больше всего на свете.

Для меня if - это тестирование , чтобы увидеть, можно ли использовать значение, а если нет, то оно обходит проблему. Блок try...catch равен , предполагая, что значение допустимо, а если нет, оно обходит аномальное поведение.

Исключения следует в первую очередь учитывать при возникновении аберрантного кода, нарушающего работу программы (деление на ноль и т. Д.).

4 голосов
/ 23 января 2012

Нет, эти кодовые блоки совсем не одинаковы.

В первом блоке кода вы проверяете, является ли myVariable значением null, и вы делаете это только в один момент времени.Позже, myVariable может стать null и в конечном итоге бросить NullPointerException.Если это произойдет, второй фрагмент кода будет перехватывать исключение, а первый - нет.

Более того, второй фрагмент кода перехватит NullPointerExceptions, который может быть сгенерирован из любого места в стеке вызовов в результате carryOn(myVariable) звонок.Это ужасно ;вы проглатываете исключение, работающее в предположении, что конкретной переменной является null, когда она может быть чем-то совершенно другим.

Использовать первый фрагмент кода.

3 голосов
/ 23 января 2012

Вы используете исключения только для исключительных случаев. Переходите к первому блоку кода, а не ко второму.

2 голосов
/ 23 января 2012

Ну, само по себе, carryOn(MyVariable); никогда не сгенерирует NPE, если только что-то в carryOn не ссылается на вызов метода или свойства для нулевого экземпляра.

Ловля исключений более затратна в вычислительном отношении, чем первая его проверка, поскольку генерация исключения требует генерации трассировки стека и т. Д.

Я бы сказал, что это также приводит к "более чистому" коду.

Смотрите также: - Производительность Java try / catch, рекомендуется ли сводить к минимуму то, что находится внутри предложения try? - Попробуйте Catch Performance Java

0 голосов
/ 23 января 2012

Первый подход лучше, чем перехват исключений, потому что существует некоторое снижение производительности.На мой взгляд, лучший подход - применить шаблон Null Object .Библиотека Guava предоставляет опциональный класс, который вы можете использовать вместо создания собственного.

...