Подтвердить что ты не робот

Бросок родового исключения не рекомендуется?

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

4b9b3361

Ответ 1

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

Ответ 2

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

Кроме того, бросая "Исключение", вы в основном говорите вызывающим вашим кодом, что они не могут исключить какой-либо класс исключения. Может возникнуть IOException, а также NumberFormatException и т.д.

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

Dittos к GH. Я бы использовал исключение "null pointer exception" и "исключение из памяти" как более очевидные примеры исключений, которые вы, вероятно, не наблюдаете, чтобы ловить в одном блоке с вашими истинными исключениями приложения.

Я бы также добавил, что платит, чтобы приложить небольшие усилия для будущей расширяемости. Если вы бросаете общие исключения по всему месту, а позже вы решаете, что вам нужно поймать некоторые исключения, а не другие, это может стать серьезной болью, чтобы вернуться и изменить их все. Но если вы просто создаете исключения, которые вам нужны, когда вы идете вперед, это не такая уж большая сделка. Создание нового класса исключений, который просто принимает конструктор с сообщением, принимает, что, 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"? Программа все еще будет компилироваться, но она не будет работать правильно.