Должны ли блоки catch использоваться для написания логики, например, для управления потоком и т. Д.? Или просто для того, чтобы бросать исключения? Влияет ли это на эффективность или удобство сопровождения кода?
Каковы побочные эффекты (если они есть) написания логики в блоке catch?
РЕДАКТИРОВАТЬ:
Я видел класс Java SDK, в котором они написали логику внутри блока catch. Например (фрагмент взят из java.lang.Integer
класса):
try {
result = Integer.valueOf(nm.substring(index), radix);
result = negative ? new Integer(-result.intValue()) : result;
} catch (NumberFormatException e) {
String constant = negative ? new String("-" + nm.substring(index))
: nm.substring(index);
result = Integer.valueOf(constant, radix);
}
EDIT2 :
Я проходил урок, где они считают это преимуществом написания логики исключительных случаев внутри исключений:
Исключения позволяют вам написать основной поток вашего кода и иметь дело с исключительными случаями в другом месте.
Какие-то конкретные рекомендации, когда писать логику в блоке catch, а когда нет?
java
programming-practices
exceptions
HashimR
источник
источник
Ответы:
Приведенный вами пример связан с плохим дизайном API (не существует чистого способа проверить, является ли String действительным целым числом, кроме попытки его анализа и перехвата исключения).
На техническом уровне throw и try / catch являются конструкциями потока управления, которые позволяют вам перепрыгивать через стек вызовов, ни больше, ни меньше. Прыжок вверх по стеку вызовов неявно соединяет код, который не находится близко друг к другу в источнике, что плохо для удобства сопровождения . Поэтому его следует использовать только тогда, когда вам нужно это сделать, а альтернативы еще хуже. Широко признается случай , когда альтернативы хуже обработки ошибок (специальные коды возврата , которые должны быть проверены и прошли вверх каждый уровень стека вызовов вручную).
Если у вас есть случай, когда альтернативы хуже (и вы действительно тщательно их рассмотрели), то я бы сказал, что использование throw и try / catch для управления процессом - это нормально. Догма не является хорошей заменой суждению.
источник
Это то, что имеет тенденцию зависеть от языка и парадигмы.
Большая часть моей работы выполняется на Java (а иногда и на C ++). Тенденция заключается в использовании исключений только для исключительных условий. В отношении переполнения стека есть несколько вопросов о накладных расходах исключений в Java , и, как вы можете видеть, это не совсем незначительно. Есть и другие проблемы, такие как читаемость и удобство сопровождения кода. При правильном использовании исключения могут делегировать обработку ошибок соответствующим компонентам.
Тем не менее, в Python, идея, что проще просить прощения, чем разрешение правит. В сообществе Python это известно как EAFP , что контрастирует с подходом «посмотри перед прыжком» ( LBYL ) в языках стиля C.
источник
Это не лучший способ думать о блоках try / catch. Способ думать о блоках try / catch заключается в следующем: произошел сбой, где лучше всего справиться с ЭТИМ конкретным отказом. Это может быть следующая строка кода, это может быть двадцать уровней вверх по цепочке вызовов. Где бы это ни было, именно там оно и должно быть.
То, что делает блок catch, зависит от ошибки и того, что вы можете с ней сделать. Иногда его можно просто проигнорировать (неудача в удалении чистого файла без каких-либо важных данных), иногда он будет использоваться для установки значения, возвращаемого функцией, равным true или false (метод int parse java), иногда вы выходите из программы , Все это зависит от ошибки.
Важная часть, чтобы понять это: ловить блок == Я знаю, как с этим бороться.
источник
Блоки Catch должны использоваться только для обработки исключений, ничего больше и никогда для потока управления. В любой ситуации, когда вы хотите использовать исключения для управления потоком, лучше проверить предварительные условия.
Обработка потока с исключениями медленная и семантически некорректная.
источник
Во-первых, забудьте о том, что «исключения должны использоваться для исключительных условий». Также перестаньте беспокоиться об эффективности, пока у вас не будет кода, который работает недопустимо, и вы не знаете, в чем проблема.
Код легче понять, когда действия выполняются в простой последовательности, без условий. Исключения улучшают удобство обслуживания, удаляя проверку ошибок из обычного потока. Не имеет значения, следует ли выполнение нормальному потоку 99,9% времени или 50% времени или 20% времени.
Выдает исключение, когда функция не может вернуть значение, когда процедура не может завершить ожидаемое действие или когда конструктор не может создать пригодный для использования объект. Это позволяет программистам предполагать, что функция всегда возвращает пригодный для использования результат, процедура всегда завершает запрошенное действие, созданный объект всегда находится в пригодном для использования состоянии.
Самая большая проблема, с которой я сталкиваюсь в коде обработки исключений, заключается в том, что программисты пишут блоки try / catch, когда они не должны этого делать. Например, в большинстве веб-приложений, если запрос к базе данных выдает исключение, в контроллере ничего нельзя сделать. Достаточно одного общего предложения по улову на самом высоком уровне. Тогда код контроллера может блаженно игнорировать вероятность того, что диск сломался или база данных отключена или что-то еще.
источник
Блоки Catch не должны использоваться для написания логики кода. Их следует использовать только для обработки ошибок. Примером является (1) очистка любых выделенных ресурсов, (2) печать полезного сообщения и (3) корректный выход.
Это правда, что исключениями можно злоупотреблять и вызывать нежелательные
goto
последствия. Но это не делает их бесполезными. При правильном использовании они могут улучшить многие аспекты вашего кода.источник