Обробка винятків
Обро́бка ви́нятків (також опрацьо́вування (обробля́ння) винятко́вих ситуа́цій[1], англ. exception handling) — механізм мов програмування, призначений для обробки помилок часу виконання й інших можливих проблем (винятків), які можуть виникнути під час виконання програми.
Загалом під час виникнення виняткової ситуації, керування передається деякому заздалегідь призначеному обробникові (опрацьовувачу). У деяких мовах, обробник може відновити виконання програми з місця виникнення винятку. Таким чином, обробка помилок передається на вищий рівень і забезпечується можливість так званого нелокального виходу, тобто передачі керування на деяку «віддалену», можливо заздалегідь невідому, точку програми через довільне число викликів функцій.
Переваги та недоліки[ред. | ред. код]
Винятки надають основні переваги під час розробки окремих компонентів, коли розробник компонента не знає, як потрібно обробити виняток і залишає написання обробника винятку користувачеві його компонента.
Використання винятків у цілях контролю помилок підвищує прочитність коду, оскільки дозволяє відокремити обробку помилок від самого алгоритму, і полегшує програмування і використання компонентів інших розробників.
Основний недолік винятків — у їхній невисокій швидкості. У місцях програми, критичних за швидкістю, не варто порушувати й обробляти винятки.
У складних програмах виникають великі «нагромадження» операторів try … finally
і try … catch
(try … except
), але без застосування механізму обробки винятків аналогічна за функціональністю програма виглядала б ще більше захаращеною.
Підтримка в різних мовах[ред. | ред. код]
Більшість сучасних мов програмування, таких як ActionScript, Ada, C++, Common Lisp, D, Object Pascal, Eiffel, Java, JavaScript, Objective-C, Objective Caml, Ruby, PHP (з версії 5), Python, SML, Глагол, всі мови платформи .NET тощо, мають вбудовану підтримку обробки винятків. У цих мовах, під час виникнення виняткової ситуації (точніше, винятку, підтримуваного мовою), відбувається розкручування стека викликів до першого обробника винятків відповідного типу, і керування передається обробникові.
За винятком незначних відмінностей у синтаксисі, існує лише пара варіантів обробки винятків. У найпоширенішому з них виняткова ситуація генерується спеціальним оператором (throw
або raise
) з об'єктом-винятком. Водночас конструювання такого об'єкта само собою викиду винятку не спричиняє. Область дії обробників починається спеціальним ключовим словом try
або просто мовним маркером початку блоку (наприклад, begin
) і закінчується перед описом обробників (catch
, except
, resque
). Обробників може бути кілька, один за одним, і кожен може вказувати тип винятку, який він обробляє.
Деякі мови також допускають спеціальний блок (else
), який виконується, якщо жодного винятку не згенерувано у відповідній області дії. Частіше зустрічається можливість безумовного виконання коду (finally
, ensure
), навіть у разі, якщо виняток було викинуто, але не оброблено. Помітним винятком є С++, де такої конструкції немає. Замість неї використовується автоматичний виклик деструкторів об'єктів. Водночас існують нестандартні розширення С++, що підтримують і функціональність finally
(наприклад в MFC).
Загалом обробка винятків може виглядати таким чином (у деякій абстрактній мові):
try {
line = console.readLine();
if (line.length() == 0)
throw new EmptyLineException("Рядок, прочитаний з консолі, пустий!");
console.printLine("Привіт, %s!" % line);
}
catch (EmptyLineException exception) {
console.printLine("Привіт!");
}
catch (Exception exception) {
console.printLine("Помилка: " + exception.message());
}
else {
console.printLine("Програма виконана без виняткових ситуацій");
}
finally {
console.printLine("Програма завершена");
}
У деяких мовах може бути лише один обробник, який розбирається з різними типами винятків самостійно.
У деяких мовах, наприклад Сі або Perl, немає вбудованої обробки винятків.
Винятки, що перевіряються[ред. | ред. код]
Спочатку (наприклад, у C++), винятки не були обов'язковими для обробки. Якщо якийсь виняток не обробляється, тобто якщо для нього немає обробника в стеку виклику, або обробник викинув виняток наново, то виконання програми уривається.
У новіших мовах, наприклад у Java, разом з «класичними» з'явилися винятки, що перевіряються. Обробка таких винятків перевіряється компілятором. Метод, у якому може виникнути виняток (зокрема й у методах, що викликаються) зобов'язаний або обробити його, або оголосити, що може викинути[куди?] такий виняток.
Переваги та недоліки[ред. | ред. код]
Винятки, що перевіряються, знижують кількість ситуацій, коли виняток, який міг бути обробленим, викликав критичну помилку в програмі, оскільки за наявністю обробників стежить компілятор. Це може бути особливо корисно, якщо метод, який не міг викидати виняток типу X став це робити: компілятор автоматично відстежить усі випадки його використання і перевірить наявність відповідного обробника.
Проте, у винятків, що перевіряються, є й недоліки. По-перше, вони часто «примушують» обробляти те, з чим програміст у принципі впоратися не може, наприклад помилку введення-виведення у вебсервері. Це приводить до появи «дурних» обробників, які не роблять нічого або виводять стек виклику винятків і, у результаті, тільки засмічують код. По-друге, це робить неможливим додавання нового винятку, що перевіряється, у методі, описаному в бібліотеці, оскільки це порушує зворотну сумісність. (Це вірно й для небібліотечних методів, але в цьому разі проблема менш істотна).
У результаті, багато бібліотек оголошують усі методи як такі, що викидають деякий суперклас винятків (наприклад, Exception
). У результаті, компілятор «примушує» писати обробники винятків навіть там, де вони, здавалося б, не потрібні.
Примітки[ред. | ред. код]
- ↑ О. Кочерга, Є. Мейнарович, Англійсько-українсько-англійський словник наукової мови (фізика та споріднені науки). Частина І англійсько-українська 2010р.
Див. також[ред. | ред. код]
Ця стаття не містить посилань на джерела. (червень 2011) |
Це незавершена стаття про програмування. Ви можете допомогти проєкту, виправивши або дописавши її. |