Вложенные операторы try

Операторы try могут быть вложенными. То есть оператор try может находиться внутри блока другого try. Всякий раз, когда управление попадает в блок try, контекст этого исключения заталкивается в стек. Если вложенный оператор try не имеет обработчика catch для определенного исключения, стек "раскручивается" и проверяются на соответствие обработчики catch следующего (внешнего) блока try. Это продолжается до тех пор, пока не будет найден подходящий оператор catch либо пока не будут проверены все уровни вложенных try. Если подходящий оператор catch не будет найден, то исключение обработает система времени выполнения Java. Ниже приведен пример, в котором используются вложенные операторы try.

// Пример вложенных операторов try.
class NestTry {
public static void main(String args[]) {
try {
int a = args.length;
/* Если не указаны параметры командной строки,
следующий оператор сгенерирует
исключение деления на ноль. *'/
int b = 42 / а;
System.out.println("а = " + a) ;
try { // вложенный блок try
/* Если используется один аргумент командной строки,
то исключение деления на ноль будет сгенерировано следующим кодом. */
if(a==l) а = а/(а-а); // деление на ноль
/* Если используется два аргумента командной строки,
то генерируется исключение выхода за пределы массива. */
if(a==2) {
int с[] = { 1 };
с [42] = 99; // генерируется исключение выхода за пределы массива
}
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Индекс за пределами массива: " + е) ;
}
}
catch(ArithmeticException е) {
System.out.println("Деление на 0: " + e);
}
}
}

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

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

С:\>java NestTry
Деление на 0: java.lang.ArithmeticException: / by zero
C:\>java NestTry One a = 1
Деление на 0: java.lang.ArithmeticException: / by zero
C:\>java NestTry One Two a = 2
Индекс за пределами массива:
j ava.lang.ArraylndexOutOfBoundsException:42

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

/* Операторы try могут быть неявно вложены в вызовах методов. */
class MethNestTry {
static void nesttry(int a) {
try ( // вложенный блок try
/* Если используется один аргумент командной строки,
то исключение деления на ноль будет сгенерировано следующим кодом. */
if(a==l) а = а/(а-а) ; // деление на ноль
/* Если используется два аргумента командной строки,
то генерируется исключение выхода за пределы массива. */
if(a==2) {
int с[] = { 1 };
с [42] = 99; // генерируется исключение выхода-за пределы массива
}
}
catch(ArraylndexOutOfBoundsException е) {
System.out.println("Индекс за пределами массива: " + е) ;
}
}
public static void main(String args[]) {
try {
int a = args.length;
/* Если не указаны параметры командной строки,
следующий оператор сгенерирует
исключение деления на ноль. */
int b = 42 / а;
System.out.println("а = " + а);
nesttry(а);
}
catch(ArithmeticException е) {
System.out.println("Деление на 0: " + e);
}
}
}

Вывод этой программы идентичен предыдущему примеру.