Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
oop-VisualWorks.pdf
Скачиваний:
28
Добавлен:
13.02.2015
Размер:
1.23 Mб
Скачать

Глава 8

Исключения и их обработка

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

ивызывать специальную обработку исключения.

Вверсии VisualWorks 7.4.1 используется механизм обработки особых ситуаций, соответствующий ANSI-стандарту и реализованный через иерархию класса GenericException (ОбщееИсключение). Этот механизм должны использовать все создаваемые приложения.

8.1.Классы исключений

Исключения представляются экземплярами класса Exception и его многочисленных подклассов, наиболее важными из которых являются Error (Ошибка) и Notification (Уведомление). В свою очередь, подклассы этих классов, определяют более специальные виды исключений. При создании приложений и, в случае необходимости, определения новых классов для специальных исключений, новый класс исключения следует создавать как подкласс Error (в ситуации, когда нельзя будет продолжать выполнение приложения), или Notifier (в ситуации, когда выполнение приложения можно будет продолжить).

Исключение работает, сотрудничая с экземпляром класса Signal, который создаёт исключение, когда ему посылается некоторый вариант сообщения #raise. Исключение хранит информацию о природе ошибки

— о сигнале (signal), который создал его, об объекте (originator), который породил его, о параметре исключения (parameter). Приложение может использовать эту информацию, чтобы определить реакцию на исключение, которая может состоять в том, чтобы прервать выполнение

8.2. Обработка исключений

129

операции, продолжить выполнение или перезапустить операцию. Все экземпляры класса Exception и его подклассов отвечают на сообщение description, возвращая строку, которая описывает данное исключение.

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

Перечислим общие классы исключений, указывая особое событие, представляемое этим классом, и выполняемое по умолчанию действие.

Таблица 8.1: Классы исключений и их действия по умолчанию

Класс иск-

Событие исключения

 

Действие по умолчанию

лючения

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ArithmeticEr-

Любая

ошибка,

возни-

Наследуется

из

класса

ror

кающая

при

вычисле-

Error.

 

 

 

 

нии арифметической опе-

 

 

 

 

 

рации.

 

 

 

 

 

 

 

 

 

Error

Любая ошибка програм-

Открыть окно уведомле-

 

мы.

 

 

 

 

 

ний.

 

 

 

MessageNot-

Сообщение

было

посла-

Наследуется

из

класса

Understood

но объекту, который

не

Error.

 

 

 

 

определяет

соответству-

 

 

 

 

 

ющего метода.

 

 

 

 

 

 

 

Notification

Любое

необычное

собы-

Ничего не делать, про-

 

тие, которое

не

вредит

должить выполнение.

 

выполнению программы.

 

 

 

 

Warning

Необычное

событие,

о

Задать вопрос,

предпо-

 

котором

 

пользователь

лагающий

ответ

Yes/No

 

должен знать.

 

 

 

(Да/Нет)

и

возвратить

 

 

 

 

 

 

 

логическое значение.

ZeroDivide

Попытка

деления

на

Наследуется

из

класса

 

нуль.

 

 

 

 

 

ArithmeticError.

 

 

 

 

 

 

 

 

 

 

 

 

8.2.Обработка исключений

Обработка по умолчанию большинства исключений приводит к отображению окна уведомления. В многих ситуаций этого достаточно. Когда же для обработки исключения требуется действие, отличное от действия по умолчанию, нужно определить свой обработчик исключения.

130

Глава 8. Исключения и их обработка

Обработчик исключения определяется через сообщение on:do:. Первый аргумент — класс исключения, за которым наблюдает обработчик. Второй аргумент — блок кода (блок обработки), который выполняется тогда, когда происходит данное исключение. Блок обработки — блок с одним аргументом. Экземпляр класса произошедшего исключения передается блоку обработки как аргумент.

Например, следующий код определяет обработчик для исключения, возникающего при попытке деления на нуль, который печатает информационное сообщение в виде строки, отображаемой в окне Transcript:

-1.0 to: 1.0 do: [ :i |

[ 10.0/i. Transcript cr; show: i printString] on: ZeroDivide

do: [:ex | Transcript cr; show: ’divideByZero’.]

].

В окне Transcript будет отображена следующая информация:

-1.0 divideByZero 1.0

Обработчик исключения обычно завершает свою работу, возвращая значение блока обработки, вместе значения блока приемника (защищенного блока). Если в дополнение к возвращению значения из блока обработки, надо ещё и выйти из метода, содержащего этот блок, то, как и в случае любого другого блока, следует использовать оператор возврата значения.

-1.0 to: 1.0 do: [ :i |

[ 10.0/i. Transcript cr; show: i printString] on: ZeroDivide

do: [:ex | Transcript cr; show: ’divideByZero’. ^ ’divideByZero abort’.]

].

В окне Transcript будет отображена следующая информация:

-1.0 divideByZero

а метод возвратит строку ’divideByZero abort’ и прекратит работу. Вместо точного указания характера исключения, можно указывать

более общее исключение. Например,

[x / y] on: Error do: [:ex | ^ ’divideByZero abort’].

8.2. Обработка исключений

131

В этом примере класс Error определяет то исключение, которое будет обрабатываться вместо исключения ZeroDivide. Тогда, в силу наследования, обработчик будет обрабатывать и исключение Error, и исключение, которое являются экземпляром его подкласса. В данном случае используется уже существующая в VisualWorks иерархия классов

GenericException

Exception

Error ArithmeticError

DomainError ZeroDivide

В примере выше возвращаемая информация минимальна, но вполне достаточна. Однако, вряд ли разумно обрабатывать каждое происходящее исключение, используя выражение, подобное такому:

[. . . некоторый код . . . ] on: Exception

do: [:ex | Transcript show: ’An exception occurred’; cr.]

Класс Exception является слишком общим, и при таком коде приложение будет так отвечать на все исключения, включая обращения к объектам Notification, которые никак не влияют на выполнение приложения.

Обработчик исключения может автоматически получать информацию о том исключении, с которым он имеет дело:

-1.0 to: 1.0 do:

 

[ :i |

 

[ 10.0/i. Transcript cr; show: i printString]

 

on: Error

 

do: [:ex | Transcript cr; show: ex description.]

].

В этом случае в окне Transcript будет отображена информация, учитывающая строку, возвращаемую возникшим исключением по сообщению description:

-1.0

Can’t divide a number by zero 1.0

Иногда нужно установить обработчик исключений так, чтобы он обрабатывал несколько исключений, которые не обязательно входят в одну ветвь иерархии. Это можно сделать, используя класс ExceptionSet. Если происходит исключение из указанных классов или их подклассов, активизируется блок обработки. Можно неявно создавать множество исклю-

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]