Вложенные блоки try


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

Может сложиться и более нетривиальная ситуация, например, когда метод, который вызывается в блоке try, сам содержит блок try. Если в блоке try метода возникает ошибка, не обрабатываемая методом, ее перехватывает внешний блок try, в котором вызывается метод.

Вообще же общий принцип обработки ситуаций при сложной схеме включения блоков try состоит в том, что при входе в очередной блок try контексты обрабатываемых этим блоком исключений записываются в стек. При возникновении ошибки этот стек начинает «раскручиваться» — контексты исключений просматриваются в обратном порядке (то есть последний занесенный в стек контекст исключения просматривается первым).

В листинге 5 приведен пример использования вложенных блоков try.

Листинг 5.Вложенные блоки try

import java.util.Random;

class NestTryDemo{

public static void main(String args[]){

Random r=new Random();

int a,b;

int c[]={-1,1};

for(int i=1;i<10;i++){

try{

a=r.nextInt(3); // значение 0,1 или 2

b=100/a; // возможно деление на ноль

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

Вложенные блоки try 271

try{

if(a==1) a=a/(a-1); // деление на ноль

else c[a]=200; // выход за границы массива

}catch(ArrayIndexOutOfBoundsException e){

System.out.println("Выход за границы массива: "+e);}

}catch(ArithmeticException e){

System.out.println("Деление на ноль: "+e);}

System.out.println("*******************************");}

}}

Как и ранее, в программе генерируются случайные числа (с помощью объекта r класса Random), объявляются две целочисленные переменные a и b, а также целочисленный массив c, состоящий всего из двух элементов (со значениями –1 и 1).

В цикле внешнего блока try последовательное выполнение команд a=r.nextInt(3) и b=100/a может закончиться генерированием исключения, поскольку среди возможных значений переменной a есть и нулевое, что, в свою очередь, означает ошибку деления на ноль. На этот случай предусмотрен блок catch внешнего блока try. В случае ошибки выполняется команда: System.out.println("Деление на ноль: "+e)

Здесь объект e класса ArithmeticException является аргументом блока catch.

Если в указанном месте программы ошибка деления на ноль не возникает, значение переменной b выводится на экран (эта переменная может принимать всего два значения: 100 при значении переменной a равном 1 и 50 при значении переменной a равном 2), после чего выполняется серия команд, заключенных во внутренний блок try. Сразу отметим, что этот блок обрабатывает только исключение, связанное с выходом за границы массива (объект класса ArrayIndexOutOfBoundsException). В случае возникновения соответствующей ошибки выполняется команда:

System.out.println("Выход за границы массива: "+e)

Что касается самого программного кода во внутреннем блоке try, то он может вызывать исключения двух типов. В частности, там с помощью условной инструкции проверяется условие равенства значения переменной aединице. Если условие соблюдается, то при выполнении команды a=a/(a-1) происходит ошибка деления на ноль. В противном случае (то есть если значение переменной aотлично от единицы) выполняется команда c[a]=200. Обращаем внимание, что внутренний блок try выполняется, только если значение переменной a равно 1 или 2, поскольку если значение этой переменной равно 0, еще раньше возникнет ошибка деления на ноль, которая перехватывается блоком catch внешнего блока try. Поэтому если во внутреннем блоке try значение переменной a отлично от единицы, это автоматически означает, что значение переменной a равно 2.

В результате при выполнении команды c[a]=200 возникает ошибка выхода за границы массива, поскольку в массиве c всего два элемента, а элемента c[2] там

просто нет.

Таким образом, во внутреннем блоке try обрабатывается ошибка выхода за границы диапазона. Если во внутреннем блоке try возникает ошибка деления на ноль, она обрабатывается блоком catch внешнего блока try. Результат выполнения программы мог бы быть следующим:

b=50

Выход за границы массива: java.lang.ArrayIndexOutOfBoundsException: 2

*******************************

b=100

Деление на ноль: java.lang.ArithmeticException: / by zero

*******************************

b=50

Выход за границы массива: java.lang.ArrayIndexOutOfBoundsException: 2

*******************************

Деление на ноль: java.lang.ArithmeticException: / by zero

*******************************

b=50

Выход за границы массива: java.lang.ArrayIndexOutOfBoundsException: 2

*******************************

b=50

Выход за границы массива: java.lang.ArrayIndexOutOfBoundsException: 2

*******************************

b=100

Деление на ноль: java.lang.ArithmeticException: / by zero

*******************************

b=100

Деление на ноль: java.lang.ArithmeticException: / by zero

*******************************

Деление на ноль: java.lang.ArithmeticException: / by zero

*******************************

Другой пример вложенных блоков try приведен в листинге 6. На этот раз в блоке try вызывается метод, у которого есть собственный блок try.

Листинг 6.Метод с блоком try

import java.util.Random;

class MethWithTryDemo{

static void nesttry(int a){

int c[]={-1,1};

try{

if(a==1) a=a/(a-1); // деление на ноль

else c[a]=200; // выход за границы массива

}catch(ArrayIndexOutOfBoundsException e){

System.out.println("Выход за границы массива: "+e);}

}

public static void main(String args[]){

Random r=new Random();

Искусственное генерирование исключений 273

int a,b;

for(int i=1;i<10;i++){

try{

a=r.nextInt(3); // значения 0, 1 или 2

b=100/a; // возможно деление на ноль

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

nesttry(a);

}catch(ArithmeticException e){

System.out.println("Деление на ноль: "+e);}

System.out.println("*******************************");}

}}

Фактически, это та же программа, что и в предыдущем примере, только код внутреннего блока try реализован в виде статического метода nesttry(), содержащего блок try. Там, где раньше был внутренний блок try, теперь вызывается метод nesttry(). Если возникает ошибка выхода за границы массива, она обрабатывается в самом методе, а ошибка деления на ноль обрабатывается во внешнем блоке try. Результат выполнения этой программы аналогичен предыдущему.



Дата добавления: 2016-06-22; просмотров: 1780;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.012 сек.