Эккель Брюс
Шрифт:
//. exceptions/OnOffException]..java
public class OnOffExceptionl extends Exception {} lll-
ll . exceptions/0n0ffException2.java
public class 0n0ffException2 extends Exception {} III ~
//• exceptions/OnOffSwitch java 11 Для чего нужно finally?
public class OnOffSwitch {
private static Switch sw = new SwitchO; static void f
throws OnOffExceptionl, 0n0ffException2 {} public static void main(String[] args) { try {
sw.onO;
// Код, способный возбуждать исключения... f;
sw off: } catch(OnOffExceptionl e) {
System.out.pri ntin("OnOffExcepti onl"); sw.offO; } catch(OnOffException2 e) {
System.out.pri ntin("OnOffExcepti on2"); sw.offO:
}
}
} /* Output-
on
off
*///:-
Наша цель — убедиться в том, что переключатель был выключен по завершении метода main, поэтому в конце блока try и в конце каждого обработчика исключения помещается вызов sw.off. Однако в программе может возникнуть неперехватываемое исключение, и тогда вызов sw.off будет пропущен. Однако благодаря finally завершающий код можно поместить в одном определенном месте:
II: exceptions/WithFinally.java 11 Finally гарантирует выполнение завершающего кода.
public class WithFinally {
static Switch sw = new SwitchO; public static void main(String[] args) { try {
sw.onO;
// Код, способный возбуждать исключения. OnOffSwitch.fO; } catch(OnOffExceptionl e) {
System out.printing"OnOffExceptionl"); } catch(OnOffException2 e) {
System out println( OnOffException2"); } finally {
sw.offO;
}
}
} /* Output:
on
off
*///:-
Здесь вызов метода sw.off просто перемещен в то место, где он гарантированно будет выполнен.
Даже если исключение не перехватывается в текущем наборе условий catch, блок finally отработает перед тем, как механизм обработки исключений продолжит поиск обработчика на более высоком уровне:
//: exceptions/AlwaysFinally.java
// Finally выполняется всегда
import static net.mindview.util Print.*:
class FourException extends Exception {}
public class AlwaysFinally {
public static void main(String[] args) {
print("Входим в первый блок try"), try {
print("Входим во второй блок try"): try {
throw new FourExceptionO, } finally {
print("finally во втором блоке try"):
}
} catch(FourException e) { System.out.println(
"Перехвачено FourException в первом блоке try"):
} finally {
System.out.println("finally в первом блоке try"):
}
}
} /^Output-
Входим в первый блок try Входим во второй блок try finally во втором блоке try Перехвачено FourException в первом блоке try finally в первом блоке try *///:-
Блок finally также исполняется при использовании команд break и continue. Заметьте, что комбинация finally в сочетании с break и continue с метками снимает в Java всякую необходимость в операторе goto.
Использование finally с return
Поскольку секция finally выполняется всегда, важные завершающие действия будут выполнены даже при возврате из нескольких точек метода:
//• excepti ons/Multi pleReturns java import static net.mindview util Print.*;
public class MultipleReturns {
public static void f(int i) {
pri nt("Инициализация. требующая завершения"), try {
print("Точка 1"), if(i == 1) return, print("Точка 2"); if(i == 2) return, print("Точка 3"), if(i == 3) return, print("Конец"), return; } finally {
ргШС'Завершение"),
}
}
public static void main(String[] args) { for (int i =1, i <=4; i++) f(i).
}
} /* Output;
Инициализация, требующая завершения
Точка 1
Завершение
Инициализация, требующая завершения Точка 1 Точка 2 Завершение
Инициализация, требующая завершения
Точка 1
Точка 2
Точка 3
Завершение
Инициализация, требующая завершения
Точка 1
Точка 2
Точка 3
Конец
Завершение *///;-
Из выходных данных видно, что выполнение finally не зависит от того, в какой точке защищенной секции была выполнена команда return.