Блок finally
Когда исключение возникает, выполнение метода имеет неровный, нелинейный путь, который изменяет нормальное прохождение потока через метод. В зависимости от того, как кодирован метод, исключение может вызвать даже преждевременный выход из него. В некоторых случаях это могло бы стать причиной ошибки. Например, если метод открывает файл для ввода и закрывает его для вывода, то вы вряд ли захотите, чтобы закрывающий файл код был обойден механизмом обработки исключений. Для реализации этой возможности и предназначено ключевое слово finally.
finally определяет блок кода, выполняющийся после того, как блок try/catch завершился и перед кодом, следующим за блоком try/catch. Блок finally будет выполняться независимо от того, было ли выброшено исключение или нет. Если исключение было выброшено, конструкции блока finally будут обрабатываться, даже если нет catch-оператора, соответствующего исключению. Предложение finally необязательно. Однако каждый оператор try требует по крайней мере одного предложения catch или finally.
Например:
// Демонстрирует finally.
class FinallyDemo {
// Выход из метода через исключение.
static void procA() {
try {
System.out.println("Внутри procA");
throw new RuntimeException("demo");
} finally {
System.out.println("finally для procA ");
}
}
// Возврат изнутри try-блока
static void procB() {
try {
System.out.println("Внутри procB");
return;
} finally {
System.out.println("finally для procB ");
}
}
// Нормальное выполнение try-блока.
static void procC() {
try {
System.out.println("Внутри procC");
} finally {
System.out.println("finally procC");
}
}
public static void main(String args[]) {
try {
procA();
} catch (Exception e) {
System.out.println("Исключение вброшено"); }
procB();
procC();
}
}
В этом примере, procA() преждевременно выходит из блока try, выбрасывая исключение. Перед самым выходом выполняется предложение finally. Оператор try метода рrосB() выходит с помощью оператора return. Здесь finally запускается перед возвратом из рrосB(). В методе рrосC() оператор try выполняется нормально, без ошибки. Однако блок finally все же реализуется.
Вывод, сгенерированный предшествующей программой:
Внутри рrосА
finally для рrосА
Исключение выброшено
Внутри рrосВ
finally для рrосВ
Внутри рrосС
finally для рrосС
Подклассы исключений
Исключение |
Значение |
ArithmeticException |
Арифметическая ошибка типа деления на нуль |
ArraylndexOutOfBoundsException |
Индекс массива находится вне границ |
ArrayStoreException |
Назначение элементу массива несовместимого типа |
ClassCastException |
Недопустимое приведение типов |
IllegalArgirnentException |
При вызове метода использован незаконный аргумент |
IllegalMonitorStateException |
Незаконная операция монитора, типа ожидания на разблокированном потоке |
IllegalStateException |
Среда или приложение находятся в некорректном состоянии |
IllegalThreadStateException |
Требуемая операция не совместима с текущим состоянием потока |
IndexOutOfBoundsException |
Некоторый тип индекса находится вне границ |
NegativeArraySizeException |
Массив создавался с отрицательным размером |
NullPointerException |
Недопустимое использование нулевой ссылки |
NumberFormatException |
Недопустимое преобразование строки в числовой формат |
SecurityException |
Попытка нарушить защиту |
StringIndexOutOfBoundsException |
Попытка индексировать вне границ строки |
OnsupportedOperationE'xception |
Встретилась неподдерживаемая операция |
Исключение |
Значение |
ClassNotFoundException |
Класс не найден |
CloneNotSupportedException |
Попытка клонировать объект, который не реализует интерфейс Cloneable |
IllegalAccessException |
Доступ к классу отклонен |
InstantiationException |
Попытка создавать объект абстрактного класса или интерфейса |
InterruptedException |
Один поток был прерван другим потоком |
NoSuchFieldException |
Требуемое поле не существует |
NoSuchMethodException |
Требуемый метод не существует |
