Обро?бка ви?нятк?в
(також
опрацьо?вування (обробля?ння) винятко?вих ситуа?ц?й
[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р.