Если перехват исключения нулевого указателя не является хорошей практикой, является ли перехват исключения хорошей? - PullRequest
15 голосов
/ 17 января 2011

Я слышал, что ловить NullPointerException - плохая практика, и я думаю, что это разумно. Позволяя NullPointerException распространяться наверх, можно было бы обнаружить, что что-то идет не так. Но много раз я видел, как многие из моих друзей ловили Exception напрямую, так что им не нужно было беспокоиться обо всех видах исключений, которые могут возникнуть в приведенном выше коде. Это хорошая практика? Какие другие виды исключений лучше оставить необработанными? И кроме того, для меня также имеет смысл обрабатывать NullPointerException над конкретным кодом, где мы уверены в источнике исключения. Так когда же обрабатывать исключения и когда их не следует обрабатывать? И какой будет список исключений, которые лучше всего оставить необработанными?

Ответы [ 6 ]

24 голосов
/ 17 января 2011

Плохая обработка исключений для покемонов.Особенно, если это пустой блок, и вы просто глотаете их.У вас есть специально типизированные исключения по той причине, что они на самом деле означают конкретные вещи в определенных контекстах (по сути, они говорят вам, что пошло не так).Итак, поймав Exception, вы говорите, что вам все равно, что это за исключения, и что вам все равно, что произошло.Вероятно, это не то, что вам нужно.

В общем, при отлове исключений следуйте этим правилам:

  • Имеет ли смысл обрабатывать исключение на этом уровне?Если да, то справиться с этим.Если нет, то распространяйте.
  • В сочетании с первым правилом «обработка» также может означать «отлов», «обертывание» и «повторное выбрасывание».Это способ предотвратить утечку абстракции, так что вызывающие вас методы не должны знать о базовой реализации.
  • Пустой блок catch не означает, что вы обработали исключение.Это называется "глотание";по крайней мере, вы хотите записать исключение.Иногда происходящее исключение на самом деле является частью логического потока вашего кода, и поэтому вы можете захотеть сделать что-то особенное (но это, простите за каламбур, скорее исключение, чем правило. Лучше проверять ситуации, которые вызывают исключения).вместо того, чтобы включать их в логический поток вашего кода).

Вы можете легко проверить наличие нулевого значения в вашем коде, поэтому нет необходимости явно перехватывать исключение нулевого указателя.Нет смысла позволять NullPointerException случаться (и это плохая практика).Даже если у вас есть какой-то код, который выдает NullPointerException, и это код, который вы не контролируете и не можете исправить, вы должны определить входные параметры, которые вызывают NullPointerException, и специально проверить их.

Другое исключение, которое вы не должны ловить, - IllegalArgumentException.Это исключение означает, что вы передали аргумент, который не имеет смысла.Вместо того, чтобы перехватывать это исключение, вы должны явно проверить свои входные параметры, чтобы убедиться, что они нормальные и не могут вызвать IllegalArgumentException.

8 голосов
/ 17 января 2011

«Причина», по которой поймать NullPointerException считается плохой практикой, не в том, что вы должны позволить этому пузыриться, когда что-то идет не так! Сказать, что любое исключение «лучше оставить необработанным», основываясь только на его типе, кажется плохой идеей.

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

Если, например, по деловым причинам вы были подключены к API, в котором есть ошибка и иногда выдается нулевой указатель, было бы вполне законно его перехватить, что-то сделать с этим или проинформировать пользователя с лучшим сообщением , Разрешение 'null' ударить по интерфейсу только потому, что кто-то сказал, что "Поймать Null Pointer Exception is bad" не имеет смысла!

Ловля java.lang.Exception может быть законной в определенных случаях, но обычно "я ленивый" не является одним из них. :) Например, если вы реализуете API и хотите быть абсолютно уверенным, что из него никогда не выйдет исключение, которого нет в спецификации, вы можете перехватить Exception и обернуть его в определенное вами исключение приложения.

5 голосов
/ 17 января 2011

Вы должны поймать исключение, только если вы можете добавить какое-то значение, сделав это. В противном случае вы должны позволить это передать вызывающему.

NullPointerException обычно является результатом ошибки в вашем коде. Как вы можете разумно исправить это в блоке catch?

Не беспокоиться об исключениях - это не хорошая практика.

3 голосов
/ 17 января 2011

В общем, единственное время, когда вы должны поймать исключение, это если вы можете обработать его осмысленным образом. Если вы не можете, просто дайте ему взорваться и завершите процесс. Например, не могли бы вы каким-то значительным образом исправить ошибку NullPointerException или ошибку ввода-вывода? Я думаю, что нет.

Мои правила обработки исключений:

  • Как правило, не перехватывайте исключения, если только вы не можете обрабатывать их осмысленно.
  • Поймать исключения на границах процесса / компьютера, зарегистрировать перехваченное исключение вместе с любым доступным вам контекстом и повторно выдать его. Если исключение является пользовательским исключением, вы можете заключить его в исключение типа, известного / полезного для вызывающего процесса, и выбросить его.
  • Вы также можете перехватывать исключения на низком уровне, где у вас есть максимально доступный контекст времени выполнения, регистрировать исключение и связанный с ним контекст, а затем перебрасывать исключение.
  • При перебрасывании используйте throw ; вместо throw caughtException ;. Использование прежнего синтаксиса сохраняет исходную трассировку стека; использование последнего синтаксиса создает новую трассировку стека, начиная с throw caughtException ; - вы теряете весь контекст и вызываете стек до точки, в которой было обнаружено исключение.
  • Вы можете, если захотите, перехватывать исключения на высоком уровне и корректно завершать процесс, регистрируя информацию об исключениях, чтобы помочь отладить и исправить основную проблему.

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

См. Книгу Бертрана Мейерса, Построение объектно-ориентированного программного обеспечения, 2-е изд. для получения дополнительной информации.

1 голос
/ 17 января 2011

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

0 голосов
/ 17 января 2011

Если у вас есть изящный способ обработки вашего исключения, полезно его перехватить, если не надеетесь, что у вызывающего абонента есть хороший способ его обработать.

...