Явное тестирование нулевого указателя намного быстрее, чем использование обработки исключений.
Для записи, большинство из oherheads в использовании исключений происходит в реализации объекта исключения. В частности, при звонке на fillInStackTrace()
, который должен:
- проверяет каждый кадр стека на наличие стека текущего потока, а
- создать структуру данных для захвата деталей фрейма стека.
В некоторых случаях вы можете уменьшить это путем повторного использования объекта исключения или путем переопределения метода fillInStackTrace()
исключения конкретного приложения, чтобы сделать его недоступным. Недостатком в обоих случаях является то, что правильные трассировки стека больше не будут доступны, чтобы помочь вам отладить неожиданные исключения. (И ни один из них не применим к примеру ФП.)
Хотя создание исключений стоит дорого, создание исключений, их распространение и отлов тоже не совсем дешевы.
Есть вторая причина, по которой явное нулевое тестирование является лучшей идеей. Учтите это:
try {
doSomething(a.field);
} catch (NullPointerException ex) {
System.err.println("a.field is null");
}
Что произойдет, если NPE произойдет во время вызова doSomething(...)
, а не во время вычисления выражения a.field
? Конечно, мы поймаем NPE, но мы неправильно его диагностируем, а затем попытаемся продолжить ... неправильно, предполагая, что a.field
не установлено или что-то в этом роде.
Отличить «ожидаемый» NPE от «неожиданного» NPE теоретически возможно, но на практике очень сложно. Гораздо более простой и надежный подход заключается в явном тестировании ожидаемых значений null
(например, с помощью оператора if
) и обработке всех NPE как ошибок.
(Я уверен, что именно это @Mitch подразумевает под «обработкой исключений как исключительных», но я думаю, что это помогает разобраться с наглядным примером ...)