Исключения - очень необычный метод управления потоком по сравнению с традиционными конструкциями (циклы, ifs, функции и т. Д.). Нормальные конструкции потока управления (циклы, ifs, вызовы функций и т. Д.) Могут обрабатывать все нормальные ситуации. Если вы обнаружите, что пытаетесь найти исключение для обычного вхождения, возможно, вам нужно подумать о том, как структурирован ваш код.
Но есть определенные типы ошибок, которые не могут быть легко обработаны с помощью обычных конструкций. Катастрофические сбои (например, сбой при распределении ресурсов) могут быть обнаружены на низком уровне, но, вероятно, не могут быть обработаны там, поэтому простой оператор if неадекватен. Эти типы сбоев, как правило, должны обрабатываться на гораздо более высоком уровне (например, сохранить файл, зарегистрировать ошибку, выйти). Попытка сообщить об ошибке, подобной этой, с помощью традиционных методов (например, возвращаемых значений) утомительна и подвержена ошибкам. Кроме того, он внедряет накладные расходы в уровни API-интерфейсов среднего уровня для обработки этого странного, необычного сбоя. Эти издержки отвлекают клиента от этих API и заставляют их беспокоиться о проблемах, которые находятся вне их контроля. Исключения обеспечивают способ нелокальной обработки больших ошибок, которые в большинстве случаев невидимы для всех уровней между обнаружением проблемы и обработчиком ее.
Если клиент вызывает ParseInt
со строкой, а строка не содержит целого числа, то непосредственный вызывающий абонент, вероятно, заботится об ошибке и знает, что с ней делать. Таким образом, вы должны разработать ParseInt для возврата кода ошибки для чего-то подобного.
С другой стороны, если ParseInt
завершится неудачно из-за невозможности выделить буфер из-за ужасной фрагментации памяти, то вызывающая сторона не будет знать, что с этим делать. Эту необычную ошибку пришлось бы всплыть до уровня, который имеет дело с этими фундаментальными ошибками. Это облагает налогом каждого между ними (потому что они должны разместить механизм передачи ошибок в своих собственных API). Исключение позволяет пропустить эти слои (при этом обеспечивая необходимую очистку).
Когда вы пишете низкоуровневый код, может быть трудно решить, когда использовать традиционные методы, а когда генерировать исключения. Код низкого уровня должен принять решение (бросить или нет). Но это код более высокого уровня, который действительно знает, что ожидается и что является исключительным.