Java. Exception. Исключения



Поддержка JavaScript отключена

SBP-Program
На главную -> Java &nbsp

&nbsp

Как известно, исключения – это события, возникающие при выполнении программы. Эти события нарушают нормальный ход вещей.

Часть кода, где возможно возникновение исключительной ситуации, охватывают блоком try. Обработчики исключений объявляются в блоке catch, который следует сразу за блоком try. Блоков catch может быть несколько для одного блока try. В блоке catch идёт обработка исключений, а его аргумент указывает тип исключения, который может обработать данный блок, т.е. тип аргумента есть тип исключения. Код, записанный в блоке catch есть обработчик исключения.

После блока(ов) ислючения может располагаться блок finally. Приемлем случай, когда нет блоков catch, но есть блок finally. Код блока finally выполняется всегда, а не только при возникновении исключения. В нем можно выполнять обязательные завершающие действия, очистку, например, закрыть поток, а не в блоке try. После finally выполнение программы продолжается со следующей строки кода.

Схематично всё выглядет так:

а может быть без блоков catch, вот так:

или без блока finally:

Рассмотрим подробнее, что происходит при возникновении исключительной ситуации.

При возникновении исключительной ситуации, формируется объект исключения, содержащий информацию об этом исключении, который передаётся системе. В таких случаях говорят, что соотвестсвующая часть программы выбрасывает исключение, т.е. формирует объект исключения и передает его системе. Далее начинается работа системы, но прежде чем мы её разберём, надо понять что такое стек вызовов.

&nbsp&nbsp Врезка

Стек вызовов(call stack) – это пследовательность вызовов методов, начиная от метода main до интересующего нас метода. Рассмотрим условный пример. Есть класс:

Здесь стек вызовов такой: main вызывает methodA(), methodA() вызывает methodB(), methodB() вызывает methodС().

&nbsp&nbsp Конец врезки

Продолжим изучение действий системы после получения ею объекта исключения (предположим, что тип объекта исключения — AnException), выброшенного каким-то методом. Пусть это будет метод methodС(), см. врезку «Стек вызовов» выше. Система начинает просматривать стек вызовов для methodС() в обратном порядке, т.е, стартуя с самого метода methodС(), перемещается в напралении main. Цель этого просмотра – найти обработчик исключения, возникшего в methodС(). Сначала система просматривает methodС(), если в нём нет нужного обработчика исключения, то переходит к methodB(), если и в нём нет, то переходит к methodA(). methodA() содержит обработчик типа AnException, вот этому-то обработчику и передаёт система объект исключения на обработку. Говорят, что обработчик захватывает (catch) исключение. Если система не нашла бы обработчик ислючения нужного типа, то выполнение программы было бы завершено.

Если бы у methodA() было несколько блоков catch, то система выбрала бы первый подходящий блок, т.е. такой блок, тип аргумента которого совпадает с типом исключения.

Имеются три категории исключений:

  • Контролируемые (checked) исключения. Например, ошибки ввода. Такие исключения рекомендуется обрабатывать;
  • Ошибка (error). Это исключения, вызванные внешними, по отношению к приложению, причинами и приложение их, как правило, не обрабатывает. Такие исключения определяются классом Error или его подклассами;
  • Исключения времени выполнения (runtime exception). Например, ошибки в коде. Такие исключения определяются классом RuntimeException или его подклассами. Эти исключения могут обрабатываться.

Исключения второго и третьего типа называют неконтролируемые (unchecked) исключения.

Метод может не обрабатывать исключение, но, предполагая, что оно может возникнуть, передать его на обработку в стек вызовов. Тогда в объявлении метода пишут оператор throws и в нём через запятую перечень возможных типов исключений. Пример:

Метод может сам выбросить исключение. Для этого используют оператор throw и объект исключения в нём. Пример:

Если этом примере a

Выбросить исключение оператором throw можно и из тела оработчика другого исключения. Так возникает цепочка исключений (chained exceptions). Пример:

Все классы исключений восходят к классу Throwable. Непосредственными наследниками его являются классы Error и Exception. От Exception происходят RuntimeException и все классы контролируемых исключений.

Мы уже знаем, что исключения типа Error обрабатывает система, мы их обычно не касаемся.

Исключения типа RuntimeException говорят об ошибках в коде. Такие исключения могут обрабатываться, но лучше просто исправить ошибки кода.

Исключения типа Exception говорят о наличии проблем, но они не являются серьёзными системными. Такие ошибки следует обрабатывать.

Можно создавать свои классы исключений как прямых или нет наследков Exception. Принято к названиям таких классов добавлять слово Exception.

Если тип аргумента оператора catch есть Exception, то соотвестсвующий обработчик исключений сможет захватить все контролируемые исключения и исключения типа RuntimeException. Так можно поступить, если нет особых требований к обработчику или если могут возникнуть непредвиденные исключения. Но если требуется особый подход, то лучше использовать наследников Exception.

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

В заключении привожу полный код примера, который рассматривался на протяжении этого раздела. Главный класс:

Класс исключения AnException:

Класс исключения NextException:

Программирование

&nbsp
&nbsp
&nbsp