Программирование на языке Java

       

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


Глава 10 Обработка исключений

В этой главе обсуждается используемый в Java механизм обработки исключений. Исключение в Java — это объект, который описывает исключительное состояние, воз­никшее в каком-либо участке программного кода. Когда возникает ис­ключительное состояние, создается объект класса Exception. Этот объект пересылается в метод, обрабатывающий данный тип исключительной ситуации. Исключения могут возбуждаться и «вруч­ную» для того, чтобы сообщить о некоторых нештатных ситуациях.

 

Основы

К механизму обработки исключений в Java имеют отношение 5 клю­чевых слов: — try, catch, throw, throws и finally. Схема работы этого механизма следующая. Вы пытаетесь (try) выполнить блок кода, и если при этом возникает ошибка, система возбуждает (throw) исключение, ко­торое в зависимости от его типа вы можете перехватить (catch) или пере­дать умалчиваемому (finally) обработчику.

Ниже приведена общая форма блока обработки исключений.

try {

// блок кода }



catch (ТипИсключения1 е) {

// обработчик исключений типа ТипИсключения1 }

catch (ТипИсключения2 е) {

// обработчик исключений типа ТипИсключения2

 throw(e)   // повторное возбуждение исключения }

finally {

}

 

ЗАМЕЧАНИЕ

В языке Delphi вместо ключевого слова catch используется except.

 

Типы исключений

В вершине иерархии исключений стоит класс Throwable. Каждый из типов исключений является подклассом класса Throwable. Два непосредственных наследника класса Throwable делят иерархию подклассов исключений на две различные ветви. Один из них — класс Ехception — используется для описания исключительных ситуации, кото­рые должны перехватываться программным кодом пользователя. Другая ветвь дерева подклассов Throwable — класс Error, который предназначен для описания исклю­чительных ситуаций, которые при обычных условиях не должны перехватываться в пользовательской программе.

 

Неперехваченные исключения

Объекты-исключения автоматически создаются исполняющей средой Java в результате возникновения определенных исключительных состо­яний. Например, очередная наша программа содержит выражение, при вычислении которого возникает деление на нуль.


class Exc0 {



public static void main(string args[]) {



int d = 0;



int a = 42 / d;



} }



Вот вывод, полученный при запуске нашего примера.

С:\> java Exc0

java.lang.ArithmeticException: / by zero



at Exc0.main(Exc0.java:4)



Обратите внимание на тот факт что типом возбужденного исклю­чения был не Exception и не Throwable. Это подкласс класса Exception, а именно: ArithmeticException, поясняющий, какая ошибка возникла при выполнении программы. Вот другая версия того же класса, в кото­рой возникает та же исключительная ситуация, но на этот раз не в про­граммном коде метода main.

class Exc1 {



static void subroutine() {



int d = 0;



int a = 10 / d;



}



public static void main(String args[]) {



Exc1.subroutine();



} }



Вывод этой программы показывает, как обработчик исключений ис­полняющей системы Java выводит содержимое всего стека вызовов.

С:\> java Exc1

java.lang.ArithmeticException: / by zero



at Exc1.subroutine(Exc1.java:4)



at Exc1.main(Exc1.java:7)



try и catch



Для задания блока программного кода, который требуется защитить от исключений, исполь­зуется ключевое слово try. Сразу же после try-блока помещается блок catch, задающий тип исключения которое вы хотите обрабатывать.

class Exc2 {



public static void main(String args[]) {



try {



    int d = 0;



     int a = 42 / d;



    }



catch (ArithmeticException e) {



System.out.println("division by zero");



}



}

}



 



Целью большинства хорошо сконструированных catch-разделов долж­на быть обработка возникшей исключительной ситуации и приведение переменных программы в некоторое разумное состояние — такое, чтобы программу можно было продолжить так, будто никакой ошибки и не было (в нашем примере выводится предупреждение – division by zero).

 



Несколько разделов catch



В некоторых случаях один и тот же блок программного кода может воз­буждать исключения различных типов. Для того, чтобы обрабатывать по­добные ситуации, Java позволяет использовать любое количество catch-разделов для try-блока. Наиболее специализированные классы исключений должны идти первыми, поскольку ни один подкласс не будет достигнут, если поставить его после суперкласса. Следующая про­грамма перехватывает два различных типа исключений, причем за этими двумя специализированными обработчиками следует раздел catch общего назначения, перехватывающий все подклассы класса Throwable.



class MultiCatch {



public static void main(String args[]) {



try {



     int a = args.length;



     System.out.println("a = " + a);



     int b = 42 / a;



     int c[] = { 1 };



     c[42] = 99;



    }



catch (ArithmeticException e) {



System.out.println("div by 0: " + e);



}



catch(ArrayIndexOutOfBoundsException e) {



System.out.println("array index oob: " + e);



}



} }



Этот пример, запущенный без параметров, вызывает возбуждение ис­ключительной ситуации деления на нуль. Если же мы зададим в командной строке один или несколько параметров, тем самым установив а в значение боль­ше нуля, наш пример переживет оператор деления, но в следующем опе­раторе будет возбуждено исключение выхода индекса за границы масси­ва ArrayIndexOutOf Bounds. Ниже приведены результаты работы этой программы, за­пущенной и тем и другим способом.

С:\> java MultiCatch

а = 0



div by 0: java.lang.ArithmeticException: / by zero



C:\> java MultiCatch 1

a = 1



array index oob: java.lang.ArrayIndexOutOfBoundsException: 42



 




Содержание раздела