Следующий фрагмент иллюстрирует синтаксис и назначение инструкции
<b>try/catch/finally</b>
:
<b>try {</b>
<b> // Обычно этот код без сбоев работает от начала до конца.</b>
<b> // Но в какой-то момент в нем может быть сгенерировано исключение </b>
<b> // либо непосредственно с помощью инструкции throw, либо косвенно -</b>
<b> // вызовом метода, генерирующего исключение.</b>
<b>}</b>
<b>catch (е) {</b>
<b> // Инструкции в этом блоке выполняются тогда и только тогда, когда в блоке try </b>
<b> // возникает исключение. Эти инструкции могут использовать локальную переменную е,</b>
<b> // ссылающуюся на объект Error или на другое значение, указанное в инструкции throw. </b>
<b> // Этот блок может либо некоторым образом обработать исключение, либо </b>
<b> // проигнорировать его, делая что-то другое, либо заново сгенерировать </b>
<b> // исключение с помощью инструкции throw.</b>
<b>}</b>
<b>finally {</b>
<b> // Этот блок содержит инструкции, которые выполняются всегда, независимо от того,</b>
<b> // что произошло в блоке try. Они выполняются, если блок try завершился:</b>
<b> // 1) как обычно, достигнув конца блока</b>
<b> // 2) из-за инструкции break, continue или return</b>
<b> // 3) с исключением, обработанным приведенным в блоке catch выше</b>
<b> // 4) с неперехваченным исключением, которое продолжает свое</b>
<b> // распространение на более высокие уровни</b>
<b>}</b>
Обратите внимание, что за ключевым словом catch следует идентификатор в скобках. Этот идентификатор похож на параметр функции. Когда будет перехвачено исключение, этому параметру будет присвоено исключение (например, объект
<b>Error</b>
). В отличие от обычной переменной идентификатор, ассоциированный с конструкцией
<b>catch</b>
, существует только в теле блока
<b>catch</b>
.
Далее приводится более реалистичный пример инструкции
<b>try/catch</b>
. В нем вызываются метод
<b>factorial(),</b>
определенный в предыдущем разделе, и методы
<b>prompt()</b>
и
<b>alert()</b>
клиентского JavaScript для организации ввода и вывода:
<b>try {</b>
<b> // Запросить число у пользователя</b>
<b> var n = Number(prompt("Введите положительное число",""));</b>
<b> // Вычислить факториал числа, предполагая, что входные данные корректны </b>
<b> var f = factorial(n);</b>
<b> // Вывести результат </b>
<b> alert(n + "! = " + f);</b>
<b>}</b>
<b>catch (ex) { // Если данные некорректны, управление будет передано сюда</b>
<b> alert(ех); // Сообщить пользователю об ошибке</b>
<b>}</b>
Это пример инструкции
<b>try/catch</b>
без конструкции
<b>finally</b>
. Хотя
<b>finally</b>
используется не так часто, как
<b>catch</b>
, тем не менее иногда эта конструкция оказывается полезной. Однако ее поведение требует дополнительных объяснений. Блок
<b>finally</b>
гарантированно исполняется, если исполнялась хотя бы какая-то часть блока
<b>try</b>
, независимо от того, каким образом завершилось выполнение программного кода в блоке
<b>try</b>
. Эта возможность обычно используется для выполнения заключительных операций после выполнения программного кода в предложении
<b>try</b>
.
В обычной ситуации управление доходит до конца блока
<b>try</b>
, а затем переходит к блоку
<b>finally</b>
, который выполняет необходимые заключительные операции. Если управление вышло из блока
<b>try</b>
как результат выполнения инструкций
<b>return</b>
,
<b>continue</b>
или
<b>break</b>
, перед передачей управления в другое место выполняется блок
<b>finally</b>
.
Если в блоке
<b>try</b>
возникает исключение и имеется соответствующий блок
<b>catch</b>
для его обработки, управление сначала передается в блок
<b>catch</b>
, а затем - в блок
<b>finally</b>
. Если отсутствует локальный блок
<b>catch</b>
, то управление сначала передается в блок
<b>finally</b>
, а затем переходит на ближайший внешний блок
<b>catch</b>
, который может обработать исключение.
Если сам блок
<b>finally</b>
передает управление с помощью инструкции
<b>return</b>
,
<b>continue</b>
,
<b>break</b>
или
<b>throw</b>
или путем вызова метода, генерирующего исключение, незаконченная команда на передачу управления отменяется и выполняется новая. Например, если блок
<b>finally</b>
сгенерирует исключение, это исключение заменит любое ранее сгенерированное исключение. Если в блоке
<b>finally</b>
имеется инструкция
<b>return</b>
, произойдет нормальный выход из метода, даже если генерировалось исключение, которое не было обработано.