Kivétel
A Wikipédiából, a szabad lexikonból.
Ezen szócikk összedolgozandó a(z) kivételkezelés szócikkel, azután az egyik lap törlendő. |
A kivételkezelés egy mechanizmus, melynek célja a program futását szándékosan vagy nem szándékolt módon megszakító esemény (hiba) vagy utasítás kezelése. Az eseményt magát kivételnek hívjuk. A hagyományos, szekvenciális és struktúrált programozási kereteken túlmutató hibakezelésre, valamint magasabb szintű hibadetekcióra, esetleg korrigálásra használható.
Tartalomjegyzék |
[szerkesztés] Bővebben - mi is ez ?
A normál hibakezelés általában körülményes, sok változó beiktatását és figyelését, valamint rengeteg feltételes utasítást igényel. Ezen túl nem is alkalmas arra, hogy például az operációs rendszer, vagy a processzor által küldött különféle jelzéseket, figyelmeztetőket elfogja.
A hagyományos hibakezelés esetén az utasítások végrehajtása jól követhető nyomvonalakon halad végig, jó esetben ugrások (például mint GOTO) nélkül.
Azonban ha az adott problémát nem kezeljük le, akkor a program defektje kárt okozhat a rendszerben: az alkalmazás leáll, vagy rossz esetben adatsérülés lesz az eredmény.
A megszakítás elvű kivételkezeléses rendszerben a hibákat könnyebb elfogni, valamint a nyelvek általában egy beépített eljárással kezelik a hibákat, ha mi nem tettük volna meg.
Ezért a kivételek használata és az ezekkel való munka mindenképpen egy magasabb szintű, felügyelt hibakezelést tesz lehetővé.
[szerkesztés] Története
A központosított hibakezelés igénye már régóta megmutatkozott a programozásban. Nem véletlen, hogy már a PRIMO, HT-1080Z és hasonló kaliberű számítógépek is támogatták ezt, az
ON ERROR GOTO
utasítással, amely hiba esetén a megfelelő kezelőrutinra adta a vezérlést.
Később, az Enterprise számítógépekben már valódi kivételkezeléssel találkozhattunk.
A PC-s világban már a DOS-os időszakban feltűntek az kivételkezelést alkalmazó nyelvek, mint a Pascal, a C, stb.
Később ez a tendencia átterjedt a script-szerű nyelvekre is (pedig érdekes módon pont az interpretált kódoknál könnyebb a magasszintű hibakezelés megvalósítása).
Így manapság szinte mindegyik komolyabb programozási nyelv alkalmazza a kivételeket ilyen-olyan formában.
[szerkesztés] Működése
Az operációs rendszer által kezelt szoftveres megszakítások felhasználása révén a különféle programnyelvek lehetőséget nyújtanak olyan blokkok beiktatására, amik a hibaesemények bekövetkeztekor reagálni tudnak.
A hibaeseményt (pl. rossz helyről olvasunk a memóriában) a processzor (illetve az operációs rendszer) érzékeli, majd szoftveres megszakítással él. A megszakításkezelő a megfelelő alkalmazás hibakezelőjére adja a vezérlést.
Ez az eljárás a veremben, vagy más adatközegben felkutatja a legközelebbi hibakezelő blokkot és oda ugrik. Ha nincs ilyen, akkor az alapértelmezett hibakezelőt használja.
[szerkesztés] Típusai
Általában két fő típusuk ismeretes:
- Operációs rendszerszintű kivételek: pl. memória elfogyása, rendszererőforrás problémák, fájlhibák, 0-val osztás, stb.
- Nyelvi szintű kivételek: általános kivételek, jelzések, eseményjelzők, kódblokk megszakítások, erőforrás felszabadító szakaszok.
Az objektumorientált programnyelvek általában objektumokba burkolják a kivételek, így lehetőséget biztosítanak arra, hogy azokat leszármaztassuk és saját elemekkel bővítsük őket, olyan plusz információk hordozására bírva ezeket, amelyekkel a szülő elemek nem rendelkeztek.
[szerkesztés] Használata
A nyelvi megjelenésük roppant egyszerű. Általában 3 szakaszban definiálhatóak és mindháromnak meghatározott szerepe van. E szakaszokból az kettőt párosítva kell használni: az elsőt, és második vagy harmadik elem közül opcionálisan választhatunk, az elérni kívánt hatás szerint.
1.) A védett (próbára tett) kódszakasz:
try: {blokk}
Ebbe a szakaszba helyezzük el azokat az utasításokat, amelyekben hibát "várunk". Tulajdonképpen kipróbáljuk, hogy történik-e hiba. Ha nem, akkor a blokkban szereplő utasítások lefutnak, majd a következő utasításhalmazhoz kerülünk.
2.) A hibakezelő szakasz:
except: {blokk}
vagy
catch: {blokk}
Ezen blokkokba kerül a végrehajtás, ha valamilyen hiba fordult elő. Általában a programnyelvek támogatják a kivételtípusok szerinti szelekciót, vagy a kivételekből információk kinyerését. E kódszakaszba tehetünk minden kezelőt, vagy reagáló elemet, amit a hiba kiküszöbölése, vagy észlelése miatt be akarunk vetni.
3.) A lezáró (erőforráskezelő) szakasz:
finally: {blokk}
E kódblokk tartalmaz minden olyan kritikus utasítást, aminek mindenképpen le kell futni - még kivétel bekövetkezte esetén is ! Vagyis ide teendő minden erőforráskezelő rutin - általában az összes felszabadító, elengedő szekvenciát ide érdemes halmozni, ami kapcsolatban lehet a védendő kódszakasszal.
Példa a használatra:
try: <fájl megnyitása> try: <olvasás a fájlból> finally: <fájl lezárása> except: <hibaüzenet küldése - nem sikerült a fájl tartalmát kinyerni>
Itt jól látható, hogy ágyazható egymásba két kivételkezelő - az egyik a hibák elfogásáért, a másikuk a fájl lezárásáért felelős.
Fontos: általában a finally tagoknak magasabb a prioritásuk, így rájuk kerül előbb a vezérlés.
4.) Kivételek előidézése:
A kivételeket nem csak elfogni, de előidézni is lehet. Ezzel nagyon kényelmessé tudjuk tenni a programozás, ugyanis mivel blokkmegszakító hatásuk van, így nem kell feltételes végrehajtási sorok tucatját tenni a kódunkba - elég egyetlen kivétel dobása ehelyett.
Így egyes kódszakaszok eseményvezérlésére is használhatjuk.
Használatuk általában:
raise {típus}
vagy
throw {típus}
esetleg egy kivétel objektum gyártása segítségével lehetséges.
Fontos: egyes programnyelveknél a kivétel helyett jobb más megoldást találni, mivel lassabb a működésük. Különösen a teljesítményigényes szakaszoknál próbáljuk kerülni őket !