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

Исключения, try . catch

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

Ключевые слова исключений try, catch, throw, throws, finally

Механизм исключительных ситуаций в Java поддерживается пятью ключевыми словами:

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

try < // блок кода >catch ( е) < // обработчик исключений типа ExceptionType1 >catch ( е) < // обработчик исключений типа ExceptionType2 >finally < // . >

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

В вершине иерархии исключений стоит класс Throwable, который наследуется от Object. Каждый из типов исключений является подклассом Throwable. Два непосредственных наследника класса Throwable делят иерархию подклассов исключений на две различные ветви. Иерархия классов представлена на рисунке.

Иерархия исключений

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

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

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

package samples; class TestException < public static void main(String args[]) < int d = 0; int a = 42 / d; System.out.println ("a = " + a); >>

В консоль будет выведено следующее сообщение.

Exception in thread "main" java.lang.ArithmeticException: / by zero at samples.TestException.main(TestException.java:8)

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

Изменим класс добавлением статического метода subroutine, в котором создадим такую же исключительную ситуацию.

package samples; public class TestException < static void subroutine() < int d = 0; int a = 10 / d; System.out.println ("a = " + a); >public static void main(String[] args) < TestException.subroutine(); >>

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

Exception in thread "main" java.lang.ArithmeticException: / by zero at samples.TestException.subroutine(TestException.java:8) at samples.TestException.main(TestException.java:14)

Перехват исключений try/catch

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

class TestException < 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

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

В следующем примере перехватывается два различных типа исключений, причем за этими двумя специализированными обработчиками следует раздел catch общего назначения, перехватывающий все подклассы класса Throwable.

class MultiCatch < static int c[] = < 1 >; public static void main(String args[]) < try < int a = args.length; System.out.println("a = " + String.valueOf(a)); int b = 23 / a; c[4] = 33; >catch (ArithmeticException e) < System.out.println("ArithmeticException : " + e.getMessage()); >catch(ArrayIndexOutOfBoundsException e) < System.out.println( "ArrayIndexOutOfBoundsException : " + e.getMessage()); >> >

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

а = 0 div by 0: java.lang.ArithmeticException: / by zero a = 1 array index oob: java.lang.ArrayIndexOutOfBoundsException:33

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

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

class MultiNest < static int c[] = < 1 >; static void checkArray() < try < c[4] = 33; >catch(ArrayIndexOutOfBoundsException e) < System.out.println "ArrayIndexOutOfBoundsException : " + e.getMessage()); >> public static void main(String args[]) < try < int a = args.length(); System.out.println("a = " + a); int b = 23 / a; checkArray(); >catch (ArithmeticException e) < System.out.println("ArithmeticException : " + e.getMessage()); >> >

Возбуждение исключений throw

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

Пример исключения, в котором сначала создается объект-исключение, затем оператор throw возбуждает исключительную ситуацию, после чего то же исключение возбуждается повторно — на этот раз уже кодом перехватившего его в первый раз раздела catch.

class TestThrow < static void method() < try < throw new NullPointerException("Exception in method"); >catch (NullPointerException e) < System.out.println(e.getMessage()); throw e; >> public static void main(String args[]) < try < method(); >catch(NullPointerException e) < System.out.println("Catch inside main : " + e.getMessage()); >> >

Результат выполнения программы приведен ниже.

Exception in method Catch inside main : Exception in method

Объявление об исключении throws

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

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

public class TestThrow < static void method() throws IllegalAccessException < try < System.out.println("inside method"); throw new IllegalAccessException ( "Exception in method"); >catch (NullPointerException e) < System.out.println(e.getMessage()); >> public static void main(String args[]) < try < method(); >catch(IllegalAccessException e) < System.out.println("Catch inside main : " + e.getMessage()); >> >
inside method Catch inside main : Exception in method

Ключевое слово finally

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

У каждого раздела try должен быть по крайней мере или один раздел catch или блок finally. Блок finally очень удобен для закрытия файлов и освобождения любых других ресурсов, захваченных для временного использования в начале выполнения метода.

Ниже приведен пример класса с двумя методами, завершение которых происходит по разным причинам, но в обоих перед выходом выполняется код раздела finally.

public class TestFinally < static void methodA() < try < System.out.println("inside methodA"); throw new RuntimeException("Exception in methodA"); >finally < System.out.println("finally inside methodA"); >> static void methodB() < try < System.out.println("inside methodB"); return; >finally < System.out.println("finally inside methodB"); >> public static void main(String args[]) < try < methodA(); >catch (Exception e) < System.out.println("Catch exception iinside main"); >methodB(); > >

В тестовом примере в методе methodA возбуждается исключение. Но перед преждевременным выходом из блока try, выполняется раздел finally. Во втором методе methodB завершается работа в try-блоке оператором return, но и при этом перед выходом из метода выполняется программный код блока finally. Результат работы тестового примера:

inside methodA finally inside methodA Catch exception iinside main inside methodB finally inside methodB

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

Наследование исключений

catch — полиморфная конструкция, т.е. catch по типу parent перехватывает исключения любого типа, которые является Parent’ом.

public class TestException < public static void main(String[] args) < try < System.err.print("level 0"); throw new RuntimeException(); System.err.print("level 1"); >catch (Exception e) < // catch Exception ПЕРЕХВАТ RuntimeException System.err.print("level 2"); >System.err.println("level 3"); > >

В результате в консоли увидим

Error и Exception из параллельных веток наследования от Throwable, поэтому catch по одному «брату» не может поймать другого «брата».

public class TestError < public static void main(String[] args) < try < System.err.println("level 0"); if (true) < throw new Error(); >System.err.println("level 1"); > catch (Exception e) < System.err.println("level 2"); >System.err.println("level 3"); > >

Результат выполения программы

level 0 Exception in thread "main" java.lang.Error at TestError.main(TestFinally.java:8)

Множественные исключения

Объявление исключений в методе может быть множественным. Пример :

import java.io.EOFException; import java.io.FileNotFoundException; public class MultiException < // объявляем исключения public static void main(String[] args) throws EOFException, FileNotFoundException < if (System.currentTimeMillis() % 2 == 0) < throw new EOFException(); >else < throw new FileNotFoundException(); >> >

Источник

Вложенный блок try catch в Java

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

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

Давайте сначала посмотрим на синтаксис, а затем обсудим это на примере.

Синтаксис

. //Main try block try < statement 1; statement 2; //try-catch block inside another try block try < statement 3; statement 4; //try-catch block inside nested try block try < statement 5; statement 6; >catch(Exception e2) < //Exception Message >> catch(Exception e1) < //Exception Message >> //Catch of Main(parent) try block catch(Exception e3) < //Exception Message >.

Пример

Здесь мы имеем глубокое (двухуровневое) вложение, что означает, что у нас есть блок try-catch внутри вложенного блока try. Чтобы вы лучше поняли, мы дали имена каждому блоку try в комментариях, такие как try-block2, try-block3 и т. д.

Вот как выглядит структура: try-block3 находится внутри try-block2, а try-block2 находится внутри основного try. Можно сказать, что основной try является прародителем try-block3. Обратитесь к объяснению, которое дано в конце этого кода.

class NestingDemo< public static void main(String args[])< //main try-block try< //try-block2 try< //try-block3 try< int arr[]= ; /* I'm trying to display the value of * an element which doesn't exist. The * code should throw an exception */ System.out.println(arr[10]); >catch(ArithmeticException e) < System.out.print("Arithmetic Exception"); System.out.println(" handled in try-block3"); >> catch(ArithmeticException e) < System.out.print("Arithmetic Exception"); System.out.println(" handled in try-block2"); >> catch(ArithmeticException e3) < System.out.print("Arithmetic Exception"); System.out.println(" handled in main try-block"); >catch(ArrayIndexOutOfBoundsException e4) < System.out.print("ArrayIndexOutOfBoundsException"); System.out.println(" handled in main try-block"); >catch(Exception e5) < System.out.print("Exception"); System.out.println(" handled in main try-block"); >> >
ArrayIndexOutOfBoundsException handled in main try-block

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

Пример 2

class Nest < public static void main(String args[])< //Parent try block try< //Child try block1 try< System.out.println("Inside block1"); int b =45/0; System.out.println(b); >catch(ArithmeticException e1) < System.out.println("Exception: e1"); >//Child try block2 try < System.out.println("Inside block2"); int b =45/0; System.out.println(b); >catch(ArrayIndexOutOfBoundsException e2) < System.out.println("Exception: e2"); >System.out.println("Just other statement"); > catch(ArithmeticException e3) < System.out.println("Arithmetic Exception"); System.out.println("Inside parent try catch block"); >catch(ArrayIndexOutOfBoundsException e4) < System.out.println("ArrayIndexOutOfBoundsException"); System.out.println("Inside parent try catch block"); >catch(Exception e5) < System.out.println("Exception"); System.out.println("Inside parent try catch block"); >System.out.println("Next statement.."); > >
Inside block1 Exception: e1 Inside block2 Arithmetic Exception Inside parent try catch block Next statement..

Это еще один пример, который показывает, как работает вложенный блок try. Вы можете видеть, что есть два блока try-catch внутри тела основного try. Мы пометили их как блок 1 и блок 2 в приведенном выше примере.

  • Block1: мы разделили целое число на ноль, и это вызвало ArithmeticException, поскольку block1 обрабатывает ArithmeticException, отображается «Exception: e1».
  • Block2: В блоке 2 возникла ArithmeticException, но catch здесь обрабатывает только ArrayIndexOutOfBoundsException, поэтому в этом случае элемент управления переходит к основному телу try-catch (parent) и проверяет обработчик захвата ArithmeticException в родительских catch. Так как перехват родительского блока try обрабатывает это исключение с помощью универсального обработчика исключений, в качестве вывода отображается сообщение «Внутри родительского блока try catch».
  • Попытка родительского контроля Catch: здесь не возникло никаких исключений, поэтому на экране появилось сообщение «Next Statement ..»

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

Средняя оценка 5 / 5. Количество голосов: 4

Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.

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

Напишите комментарий, что можно добавить к статье, какой информации не хватает.

Источник

Читайте также:  Заголовок документа
Оцените статью