Objektumorientált programozás Pál László Sapientia EMTE, Csíkszereda, 2014/2015
9. ELİADÁS Kivételkezelés (Exception handling) 2
Mi a kivétel (exception)? A kivétel, olyan hibás állapot vagy esemény, amely megszakítja az alkalmazás futását. Az eseményt magát kivételnek hívjuk A kiváltódásnak több oka is lehet, például felhasználói hiba, logikai hiba vagy éppen rendszerhiba A hiba kezelése hagyományos módon általában feltételek segítségével történik, melyekben valamilyen változók, hibakódok, függvények és eljárások visszaadási értékeit figyeljük. Ennek a módszernek több hátránya is van, például a függvények visszatérítési értékét figyelni kell és hiba esetén fel kell szabadítani az erıforrásokat, jelenteni kell a hívónak 3
Mi a kivétel (exception)? A kivételkezelés a.net keretrendszer egy olyan beépített mechanizmusa, melynek segítségével megtalálhatjuk és kezelhetjük a futásidejő hibákat. A.NET keretrendszer többféle beépített kivétellel rendelkezik. Ha a programozó nem biztosít megoldást ezeknek a kivételeknek a kezelésére, akkor a.net keretrendszer futtató környezete nyújt általános megoldást Kivételek segítségével a programlogika és a hibakezelés szétválasztható, ezáltal nı az áttekinthetıség 4
Kivételosztályok VB.NET-ben a futásidejő hibák kivételekké alakulnak. Ilyenkor a vezérlés a futó program aktuális pontjáról a kivételkezelıhöz (exception handler) adódik át. A kivétel, feldolgozása után automatikusan megszőnik A kivétel tehát egy hibaobjektum, amelynek osztálya valamelyik kivételosztály lehet. 5
Kivételosztályok hierarchiája 6
Kivételosztályok hierarchiája Gyakoribb kivételtípusok (objektumosztályok) 7
Kivételosztályok hierarchiája IO kivételtípusok (Névtér: System.IO) 8
Kivételek mechanizmusa A kivételek egész mechanizmusa három kulcsszón alapszik: try: a védett kód kezdetét jelzi, amelyben elıreláthatóan bekövetkezhet a hiba catch: a védett kód végét jelenti, a kivételek kezelésére szolgáló parancsokat tartalmazza finally: annak a programrésznek az elejét jelzi, amely minden esetben végrehajtódik, akár bekövetkezett a kivétel, akár nem. Ezt a részt általában a lefoglalt memória felszabadítására, megnyitott fájlok bezárására használjuk. raise: kivétel generálására szolgál. A legtöbb kivételt, amivel a Delphiben találkozunk, a rendszer generálja, de bizonyos esetekben van értelme saját kivételek kiváltására is. 9
Kivételek mechanizmusa A futási hiba keletkezésekor két dolgot kell megoldani: Le kell kezelnünk a megfelelı módon Fel kell szabadítani a hiba elıtt lefoglalt erıforrásokat: memória felszabadítás, nyitott állományok bezárása, adatbázis bezárása, stb. A továbbiakban a fenti két mőveletet tekintjük át 10
Védelem a futás-idejő hibák ellen Objektumorientált programozás - Pál László A kivételek figyelése és kezelése a következı utasítás segítségével történik: A próba-blokk az esetlegesen kivételhez vezetı utasításokat tartalmazza. A kivétel-blokkokat a nekik megfelelı kivétel létrejöttekor hajtja végre a program. A végül-blokk utasításai a kivételkezelés után kerülnek sorra 11
Védelem a futás-idejő hibák ellen Objektumorientált programozás - Pál László A kivétel egy Exception vagy belıle leszármazott típusú objektumot deklarál, melynek segítségével elérhetık a kivétel tulajdonságai. Az objektum Message tulajdonsága megadja a kivétel angol nyelvő leírását. Egy kivétel létrejöttekor megszakad a próba-blokk további utasításainak a végrehajtása. A végül-blokk akkor is végrehajtásra kerül (ha van), ha nem jön létre kivétel Az Exception típusú objektumok tulajdonságai és metódusai: 12
Védelem a futás-idejő hibák ellen Objektumorientált programozás - Pál László Példa: hibakezelés hagyományos módon és kivételkezeléssel. A feladat: hányados-számolás. Ha nem egészszámokat adunk meg, illetve az osztó nulla, a program egy megfelelı üzenetet küld. Ellenırzés nélküli kód: 13
Védelem a futás-idejő hibák ellen Objektumorientált programozás - Pál László Példa: ellenırzés nélküli hibalehetıségek (konverziós hiba) 14
Védelem a futás-idejő hibák ellen Objektumorientált programozás - Pál László Példa: ellenırzés nélküli hibalehetıségek (nullával való osztás) 15
Védelem a futás-idejő hibák ellen Objektumorientált programozás - Pál László Példa: a feladat megvalósítása hagyományos módon. 16
Védelem a futás-idejő hibák ellen Objektumorientált programozás - Pál László Példa: a feladat megvalósítása hagyományos módon. 17
Védelem a futás-idejő hibák ellen Objektumorientált programozás - Pál László Példa: a feladat megvalósítása kivételkezeléssel 18
Kivételek sorrendje A Try-Catch-ben a kivételosztályok felsorolásának sorrendje nem minden esetben tetszıleges. Akárcsak a Case utasításnál, a rendszer itt is a beírás sorrendjében ellenırzi a kivételosztályokat. Az elsı találathoz írt utasításokat végrehajtja, és nem keres tovább. Akkor van találat, amikor a vizsgált kivételosztály típus szerint kompatibilis az aktuális hiba kivételével. Emiatt, elıbb mindig a származtatott kivételosztályok kezelıit soroljuk fel. Helyes sorrend Rossz sorrend 19
Erıforrások biztonságos használata (Try...Finally) Ha egy erıforrást lefoglalunk (pld. fájl megnyitása), akkor gondolnunk kell ennek felszabadítására, még ha hiba keletkezik akkor is. VB.NET-ben ezt a Try-Finally utasítás segítségével oldhatjuk meg: A try-finally-end try szerkezet lényege, hogy a finally-end try közötti mőveletsor végrehajtódik abban az esetben is, ha a try-finally közötti rész normálisan ér véget, valamint akkor is, ha abban kivétel keletkezik. 20
Erıforrások biztonságos használata (Try...Finally) 1.Példa: A Finally-End Try törzsében található utasítás minden körülmények között lefut. Ebben az esetben, annyi a probléma hogy nincs kivételkezelés, viszont ez is megoldható kód egymásba ágyazással az alábbiak szerint: 21
Erıforrások biztonságos használata (Try...Finally) 1.Példa: fájlok kezelése 22
Kérdések Mi a különbség a klasszikus több őrlapos alkalmazás és az MDI alkalmazás között? 23
Kérdések Mi a különbség a modális és nem modális ablakok között a futásukat tekintve? 24