Бросать универсальное исключение не рекомендуется? - PullRequest
12 голосов
/ 01 ноября 2011

Почему не рекомендуется генерировать универсальное (java.lang.Exception) исключение, когда этого обычно достаточно для обработки большинства условных сбоев в методе?Я понимаю, что если метод может выдавать несколько типов исключений, то выбрасывание определенных подклассов исключения может немного прояснить обработку, но в общем случае сбой / успех я думаю, что Исключение служит более чем адекватным.

Ответы [ 5 ]

20 голосов
/ 01 ноября 2011

Проблема в том, что Exception также является суперклассом RuntimeException, который включает в себя некоторые вещи, которые не должны быть перехвачены, поскольку указывает на проблему с программированием, а не на исключительное условие, которое возникает из контекста.Вы не хотите перехватывать исключение BufferOverflowException или UnsupportedOperationException при обычных обстоятельствах.Кроме того, создание отдельных типов исключений дает вызывающему коду контроль над тем, как обрабатывать каждый из них.Boilerplate уменьшен в Java 7 благодаря новой функции multi-catch.

5 голосов
/ 01 ноября 2011

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

Кроме того, выбрасывая само «Исключение», вы в основном сообщаете вызывающим программам, что онине может исключать любой класс исключения.IOException может произойти, как и NumberFormatException и т. Д.

3 голосов
/ 01 ноября 2011

Как всегда: это зависит.

Я думаю, что есть разница между API, который вы выставляете другим.Это может жить некоторое время.В этом случае вы не знаете, что звонящий считает лучшим для своего случая.

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

1 голос
/ 01 ноября 2011

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

0 голосов
/ 01 ноября 2011

То же самое в GH.Я бы использовал «исключение нулевого указателя» и «исключение из нехватки памяти» в качестве более очевидных примеров исключений, которые вы, вероятно, не смотрите, чтобы перехватить один и тот же блок с вашими истинными исключениями приложения.

IТакже добавлю, что стоит приложить немного усилий для расширения в будущем.Если вы генерируете универсальные исключения повсеместно, а потом решаете, что вам нужно перехватывать некоторые исключения, а не другие, может быть серьезной болью вернуться и изменить их все.Но если вы просто создаете необходимые исключения по мере продвижения, это не так уж и важно.Создание нового класса исключения, который просто принимает конструктор с сообщением, занимает, что, 5 строк кода?Это хорошая инвестиция в будущее.

Как и многие вещи в программировании, вопрос в том, как далеко вы зайдете.Я обычно создаю довольно общее «BadInputException» почти в каждом проекте, над которым я работаю, и выбрасываю его каждый раз, когда пользовательские входные данные не соответствуют критериям проверки.Тогда я могу просто поймать BadInputException и выбросить сообщение на экран.Если я создаю сложный класс, который генерирует исключения для несогласованных данных и тому подобное, я обычно создаю класс исключений для него.Например, если я создаю класс TalkToDatabase, я создаю исключение TalkToDatabaseException.(Может быть, даже больше, если есть несколько видов исключений, которые, я знаю, я хочу поймать, но, по крайней мере, одно.)

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

// Very bad idea! Don't do this!
catch (Exception ex)
{
  if (ex.getMessage().equals("Invalid foo"))
  ... handle bad foo ...
  else if (ex.getMessage().equals("Plugh is over maximum"))
  ... handle bad plugh ...
  ... etc ...
}

. Было бы намного лучше просто создать отдельные исключения для этих случаев.Мало того, что обработка будет намного более эффективной, но предположим, что вы делаете вышеупомянутое, и кто-то приходит позже и решает изменить сообщение на «Foo is invalid»?Программа по-прежнему будет компилироваться, но не будет работать правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...