Оператори try, catch і finally

Щоб перехопити виняток, необхідно помістити фрагмент програми в оператор

try Базовий синтаксис оператора try виглядає наступним чином:

try

блок

catch (тип-виключення ідентифікатор)

блок

catch (тип-виключення ідентифікатор)

блок

….. finally

блок

Тіло оператора try виконується аж до порушення виключення або до успішного завершення Якщо виникає виняток, то по порядку проглядаються всі умови catch, поки не буде знайдено виняток потрібного класу або одного з його суперкласів Якщо підходяще умова catch так і не знайдено, то виключення виходить з поточного оператора try у зовнішній, який може обробити його У операторі try може бути присутнім будь-яку кількість умов catch, в тому числі і жодного Якщо жодна з умов catch всередині методу не перехоплює виняток, то воно передається в той фрагмент програми, який викликав даний метод

Якщо в try присутній умова finally, то складові його оператори виконуються після того, як вся обробка всередині try буде завершена Виконання finally відбувається незалежно від того, як завершився оператор – нормально, в результаті виключення або при виконанні керуючого оператора типу return або break

У наводиться нижче здійснюється підготовка до обробки одного з винятків, порушуваних в replaceValue:

try {

attributedObjreplaceValue(&quotAge&quot,  new Integer(8))

} catch (NoSuchAttributeException e) {

/ / Так не повинно бути, але якщо вже сталося – відновити Attr attr = new Attr (eattrName, enewValue) attrbuteObjadd (attr)

}

try містить оператор (що представляє собою блок), який виконує деякі дії, в звичайних умовах закінчуються успішно Якщо все йде нормально, то робота блоку на цьому завершується Якщо ж під час виконання програми в try-блоці порушила якесь виключення (прямо, за допомогою throw, або побічно, через внутрішній виклик методу), то виконання коду всередині try припиняється, і проглядаються повязані з ним умови catch, щоб визначити, чи потрібно перехоплювати виняток

Умова catch чимось нагадує впроваджений метод з одним параметром-типом перехоплюваних винятку Усередині умови catch ви можете намагатися відновити роботу програми після події винятку або ж виконати деякі дії і повторно порушити виняток, щоб викликає фрагмент також мав можливість перехопити його Крім того, catch може зробити те, що вважатиме за потрібне, і припинити свою роботу – в цьому випадку управління передається оператору, наступному за оператором try (після виконання умови finally, якщо воно є)

Універсальне умова catch (наприклад, перехоплювали виключення типу Exception) зазвичай говорить про погано продуманої реалізації, оскільки воно буде перехоплювати всі виключення, а не тільки те, яке нас цікавить Якщо скористатися подібним умовою у своїй програмі, то в результаті при виникненні проблем з атрибутами буде оброблятися, скажімо, виняток ClassCastException

Умови catch в операторі try проглядаються по черзі, від першого до останнього, щоб визначити, чи може тип обєкта-виключення присвоюватися типу, оголошеному в catch Коли буде знайдено умова catch з відповідним типом, відбувається виконання його блоку, причому ідентифікатором в заголовку catch присвоюється посилання на обєкт-виняток Інші умови catch при цьому не виконуються З оператором try може бути повязано довільне число умов catch, якщо кожне з них перехоплює новий тип винятку

Оскільки умови catch проглядаються по черзі, перехоплення виключення деякого типу перед перехопленням винятку розширеного типу є помилкою Перша умова завжди буде перехоплювати виключення, а друге – ніколи З цієї причини

розміщення умови catch для виключення-суперкласу перед умовою для одного з його

підкласів викликає помилку під час компіляції:

class SuperException extends Exception { }

class SubException extends SuperException { }

class BadCatch {

public void goodTry() {

/ * Неприпустимо порядок перехоплення виключень * /

try {

throw new SubException()

} catch (SuperException superRef) {

/ / Перехоплює і SuperException, і SubException

} catch (SubException subRef) {

/ / Ніколи не виконується

}

}

}

У кожному операторі try обробляється тільки один винятковий випадок Якщо catch або finally збуджують нове виключення, то умови catch даного try не розглядаються повторно Код в умовах catch і finally знаходиться за межами захисту

оператора try Зрозуміло, що виникають у них виключення можуть бути оброблені будь-яким зовнішнім блоком try, для якого внутрішні catch або finally є вкладеними

741 Умова finally

Умова finally оператора try дозволяє виконати деякий фрагмент програми незалежно від того, відбулося виключення чи ні Зазвичай робота такого фрагмента зводиться до чистці внутрішнього стану обєкта або звільнення необєктних ресурсів (наприклад, відкритих файлів), що зберігаються в локальних змінних Наведемо приклад методу, який закриває файл після завершення своєї роботи навіть у разі виникнення помилки:

public boolean searchFor(String file, String word)

throws StreamException

{

Stream input = null

try {

input = new Stream(file)

while (inputeof())

if (inputnext() == word)

return true

return false / / Пошук завершився невдало

} finally {

if (input = null)

inputclose()

}

}

Якщо створення обєкта оператором new закінчиться невдало, то input збереже своє початкове значення null Якщо ж виконання new буде успішним, то input буде містити посилання на обєкт, що відповідає відкритому файлу Під час виконання умови finally потік input буде закриватися лише в тому випадку, якщо він попередньо був відкритий Незалежно від того, чи виникло виняток при роботі з потоком чи ні, умова finally забезпечує закриття файлу завдяки цьому економиться такий обмежений ресурс, як кількість одночасно відкритих файлів Метод searchFor оголошує про те, що він збуджує StreamException, щоб все породжені в ньому виключення після виконання завершальних дій передавалися в викликає фрагмент програми

Умова finally може також використовуватися і для виконання завершальних дій після операторів break, continue і return – ось чому іноді можна зустріти try без відповідних йому catch При обробці будь-якого оператора, що передає управління програми в іншу точку, виконуються всі умови finally Неможливо покинути try-блок без виконання його умови finally

У наведеному вище прикладі finally використовується і для виконання завершальних дій у разі нормального повернення по оператору return Один з найпоширеніших випадків використання goto в інших мовами – необхідність виконання певних дій при завершенні програмного блоку, як успішному, так і аварійному У нашому прикладі finally забезпечує закриття файлу і при

виконанні оператора return, і при порушенні винятку

У умови finally завжди є деяка причина Вона може складатися в нормальному завершенні блоку try, або у виконанні керуючого оператора зразок return, або ж в порушенні винятку у фрагменті, укладеному в try-блок Ця причина запамятовується і при виході з блоку finally Проте, якщо в блоці finally виникає нова причина виходу (скажімо, виконується керуючий оператор начебто break або return або збуджується виключення), то вона скасовує стару, і про існування останньої забувається Наприклад, розглянемо наступний фрагмент:

try {

/ / .. Зробити що-небудь .. return 1

} finally {

return 2

}

Коли виконується return всередині блоку try, то на вході блоку finally код повернення дорівнює 1 Проте всередині самого блоку finally повертається значення 2, так що вихідний код повернення забувається По суті, якби в блоці try було порушено виняток, то код повернення також був би рівний 2 Якби блок finally не повертав ніякого

значення, а просто завершувався нормальним чином, то код повернення був би рівний 1

Джерело: Арнольд К, Гослінг Д – Мова програмування Java (1997)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*