try catch

Материал из Энциклопедия о программировании
Перейти к: навигация, поиск

try catch (try catch finally) — конструкция/блок отлова исключений (ошибок) во время выполнения (runtime), присутствующая в большинстве объектно-ориентированных языков программирования.

Распространённость

Конструкция try catch присутствует в любом современном развитом объектно-ориентированном языке программирования — Java, C#, etc.

Принцип работы

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

Наличие конструкции try catch сообщает о том, что в языке есть:

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

Схожести

По своей работе он очень похож на оператор множественного ветвления switch case. То есть, так же происходит наблюдение за одним блоком и далее по порядку следуют блоки с наиболее подходящим вариантом, а в конце может следовать универсальный блок. Принцип работы идентичный: происходит наблюдение за блоком try и отлов ошибки, если таковая имеется. Дальше тип ошибки сравнивается с типами описанными в идущих по-очереди на расширение выборки блоках catch, то есть управление передаётся подходящему блоку catch. Если нужно обязательное выполнение, а никакие из условий в блоках catch не подошли, то подобно блоку default в операторе switch case, в try catch есть блок finally, который обычно идёт последним после всех блоков catch. В отличие от конструкции switch case в try catch блоку finally передаётся управление НЕ только в случае, если все блоки catch будут пропущены, а всегда, вне зависимости от блоков catch. Finally выполняется всегда, даже когда ошибки происходят в блоках catch и их выполнение прекращается, при этом выполнится finally и программа перестанет выполняться.

Syntax

try {
	// doubtful code
} catch (ExceptionType1 var) {
	// notification code 1
} catch (ExceptionType2 var) {
	// notification code 2
} finally {
	// notification code 3
}

Блок try

Блок try (пытаться) содержит сомнительный код, который может вызвать исключение.

Блок catch

Блоку catch присуще следующие свойства:

  • Множественность, то есть блоков catch (поймать) может быть сколько угодно в конструкции try catch.
  • Блок catch принимает параметр в виде объекта конкретного исключения.

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

Блок finally

Код в блоке finally (финализация) выполняется всегда. Это сделано для того, чтобы можно было отловить абсолютно все типы исключений, если они появятся в блоке try. Дело в том, что в блоках catch (в большинстве случаев) отлавливаются лишь исключения конкретных типов (в некоторых языках в блоке catch можно отлавливать все исключения, если не указать их тип в круглых скобках), и порой невозможно заранее знать все типы возможных исключений, но отловить их нужно обязательно. Для этого и был придуман блок finally, который является необязательным.

Блоку finally выполняет следующие условия:

  • Необязательный в конструкции try catch, то есть может отсутствовать.
  • Единственный в конструкции try catch в отличие от блоков catch, всегда находится в конце.
  • Так же как и try, блок finally не имеет параметров, в отличие от блоков catch.
  • Выполняется всегда вне зависимости от возникновения исключения и его обработки (было ли поймано или нет).

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

Принцип работы с исключениями

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

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

Examples

Отлов исключения при делении на ноль в Java:

try {
	int a = 100 / 0;
} catch (IllegalArgumentException e) {
	System.out.println("Exception class/type: " + e.getClass() + ", exception message: " + e.getMessage());
} catch (ArithmeticException e) {
	System.out.println("Exception class/type: " + e.getClass() + ", exception message: " + e.getMessage());
} finally {
	System.out.println("The 'try catch' block is finished.");
}

Бросание пользовательского исключения в блоке try при помощи оператора throw, отлов исключения и взятие у него соответствующего сообщения, вывод сообщения пойманного исключения в блоке finally:

String errorMessage = null;
try {
	throw new Exception("Let's throw some exception message here");
} catch (Exception e) {
	System.out.println("In Exception block.");
	errorMessage = e.getMessage();
} finally {
	System.out.println(errorMessage);
}