Обработка исключений
Материал из Википедии — свободной энциклопедии
Обработка исключений или исключительных ситуаций (англ. exception handling) — механизм языков программирования, предназначенный для обработки ошибок времени выполнения и других возможных проблем (исключений), которые могут возникнуть при выполнении программы.
В целом, при возникновении исключительной ситуации, управление передаётся некоторому заранее определённому обработчику. В некоторых языках, обработчик может возобновить выполнение программы с места возникновения исключения. Таким образом, обработка ошибок передаётся на более высокий уровень и обеспечивается возможность так называемого нелокального выхода, т. е. передачи управления на некоторую «удалённую», возможно заранее неизвестную, точку программы через произвольное число вызовов функций.
[править] Достоинства и недостатки
Исключения предоставляют основные преимущества при разработке отдельных компонентов, когда разработчик компонента не знает, как нужно обработать исключение и оставляет написание обработчика исключения пользователю его компонента.
Использование исключений в целях контроля ошибок повышает читаемость кода, так как позволяет отделить обработку ошибок от самого алгоритма, и облегчает программирование и использование компонентов других разработчиков.
Основной недостаток исключений – в их невысокой скорости. В местах программы, критичных по скорости, не стоит возбуждать и обрабатывать исключения.
Также в сложных программах возникают большие «нагромождения» операторов try
/finally
и try
/catch
.
[править] Поддержка в различных языках
Большинство современных языков программирования, такие как Ada, C++, D, Delphi, Objective-C, Java, Eiffel, OCaml, Ruby, Python, Common Lisp, SML, PHP и все языки платформы .NET и др. имеют встроенную поддержку обработки исключений. В этих языках, при возникновении исключения (точнее, исключения, поддерживаемого языком), происходит раскрутка стека вызовов до первого обработчика исключений подходящего типа, и управление передаётся обработчику.
За исключением незначительных различий в синтаксисе, существует лишь пара вариантов обработки исключений. В наиболее распространённом из них исключительная ситуация генерируется специальным оператором (throw
или raise
) с объектом-исключением. При этом, конструирование такого объекта само по себе выброса исключения не вызывает. Область действия обработчиков начинается специальным ключевым словом try
или просто языковым маркером начала блока (например, begin
) и заканчивается перед описанием обработчиков (catch
, except
, resque
). Обработчиков может быть несколько, один за одним, и каждый может указывать тип исключения, который он обрабатывает.
Некоторые языки также допускают специальный блок (else
), который выполняется, если ни одного исключения не было сгенерировано в соответствующей области действия. Чаще встречается возможность безусловного выполнения кода (finally
, ensure
), даже в случае если исключение было выброшено, но не обработано. Заметным исключением является Си++, где такой конструкции нет. Вместо неё используется автоматический вызов деструкторов объектов. Вместе с тем существуют нестандартные расширения Си++, поддерживающие и функциональность finally
(например в MFC).
В целом, обработка исключений может выглядеть следующим образом (в некотором абстрактном языке):
try { line = console.readLine(); if (line.length() == 0) throw new EmptyLineException("Строка, считанная с консоли, пустая!"); console.printLine("Привет, %s!" % line); } catch (EmptyLineException exception) { console.printLine("Привет!"); } catch (Exception exception) { console.printLine("Ошибка: " + exception.message()); } else { console.printLine("Программа выполнилась без исключительных ситуаций"); } finally { console.printLine("Программа завершается"); }
В некоторых языках может быть лишь один обработчик, который разбирается с различными типами исключений самостоятельно.
В некоторых языках, например Си или Перл, нет встроенной обработки исключений.
[править] См. также
- Setjmp/longjmp