Обробка виняткових ситуацій
Конструкція try-catch
У загальному випадку конструкція виглядає так:
try {
...
} catch(SomeExceptionClass e) {
...
} catch(AnotherExceptionClass e) {
...
}
Працює вона в такий спосіб. Спочатку виконується код, який знаходиться у фігурних дужках оператора try. Якщо під час його виконання не відбувається ніяких позаштатних ситуацій, то далі керування передається за закриваючу фігурну дужку останнього оператора catch, асоційованого з даним оператором try.
Якщо в межах try виникає виняткова ситуація, то далі виконання коду виробляється по одному з перерахованих нижче сценаріїв.
Виникла виняткова ситуація, клас якої зазначений як параметр одного із блоків catch. У цьому випадку провадиться виконання блоку коду, асоційованого з даним catch (ув'язненого у фігурні дужки). Далі, якщо код у цьому блоці завершується нормально, те й весь оператор try завершується нормально й керування передається на оператор (вираження), що випливає за закриваючою фігурною дужкою останнього catch. Якщо код в catch завершується не штатно, то й весь try завершується нештатно по тій же причині.
Якщо виникла виняткова ситуація, клас якої не зазначений як аргумент у жодному catch, те виконання всього try завершується нештатно.
Конструкція try-catch-finally
Оператор finally призначений для того, щоб забезпечити гарантоване виконання якого-небудь фрагмента коду. Поза залежністю від того, чи виникла виняткова ситуація в блоці try, чи заданий підходящий блок catch, чи не виникла помилка в самому блоці catch, - однаково блок finally буде зрештою виконаний.
Послідовність виконання такої конструкції наступна: якщо оператор try виконаний нормально, те буде виконаний блок finally. У свою чергу, якщо оператор finally виконується нормально, то й весь оператор try виконується нормально.
Якщо під час виконання блоку try виникає виключення й існує оператор catch, що перехоплює даний тип виключення, відбувається виконання пов'язаного з catch блоку. Якщо блок catch виконується нормально, або ненормально, однаково потім виконується блок finally. Якщо блок finally завершується нормально, то оператор try завершується так само, як завершився блок catch.
Якщо в списку операторів catch не перебуває такого, котрий обробив би виникле виключення, те однаково виконується блок finally. У цьому випадку, якщо finally завершиться нормально, весь try завершиться ненормально по тій же причині, по якій було порушене виконання try.
У всіх випадках, якщо блок finally завершується ненормально, те весь try завершиться ненормально по тій же причині.
Розглянемо приклад застосування конструкції try-catch-finally.
try {
byte [] buffer = new byte[128];
FileInputStream fis =
new FileInputStream("file.txt");
while(fis.read(buffer) > 0) {
... обробка даних ...
}
} catch(IOException es) {
... обробка виключення ...
} finally {
fis.flush();
fis.close();
}
Якщо в даному прикладі помістити оператори очищення буфера й закриття файлу відразу після закінчення обробки даних, то при виникненні помилки уведення/виводу коректного закриття файлу не відбудеться. Ще раз відзначимо, що блок finally буде виконаний у кожному разі, поза залежністю від того, відбулася обробка чи виключення ні, виникло це чи виключення ні.
В конструкції try-catch-finally обов'язковим є використання однієї із частин оператора catch або finally. Тобто конструкція
try {
...
} finally {
...
}
є цілком припустимою. У цьому випадку блок finally при виникненні виняткової ситуації повинен бути виконаний, хоча сама виняткова ситуація оброблена не буде й буде передана для обробки на більше високий рівень ієрархії.
Якщо обробка виняткової ситуації в коді не передбачена, то при її виникненні виконання методу буде припинена й виняткова ситуація буде передана для обробки коду більше високого рівня. Таким чином, якщо виняткова ситуація відбудеться у викликуваному методі, то керування буде передано зухвалому методу й обробку виняткової ситуації повинен зробити він. Якщо виняткова ситуація виникла в коді найвищого рівня (наприклад, методі main()), то керування буде передано виконуючій системі Java і виконання програми буде припинене (більш точно - буде зупинений потік виконання, у якому відбулася така помилка).
