13. VýjimkyVýjimka (exception) je definována jako událost, která nastane během provádění programu a která naruší normální běh instrukcí. Výjimka je vyvolána například při chybném otevření souboru, při překročení mezí pole, při aritmetické chybě apod. Mechanismus výjimek umožňuje tyto chybové stavy zachytit a ošetřit. K tomu slouží dvojice bloků try a catch, jejichž syntaxe je následující:
try { // hlídaný blok } catch( třídaVýjimek1 jménoProměnné1 ) { // ošetření výjimky } catch( třídaVýjimek2 jménoProměnné2 ) { // ošetření výjimky }
Všimněte si, že díky výjimkám je důsledně oddělen "užitečný kód" od kódu, který pouze ošetřuje chyby. Výjimka jedné třídy může být navíc vyvolána v hlídaném bloku na několika místech a k ošetření postačuje jeden blok catch. Ve srovnání s klasickým způsobem testování chyb (příkazem if) je zachycování chyb pomocí výjimek mnohem přehlednější. 13.1. Třídy výjimekRodičovskou třídou všech výjimek je Throwable (z balíku java.lang), která má standardně dva přímé potomky:
Část stromu výjimek třídy Exception vypadá takto: Díky objektové hierarchii výjimek je možné zachytit více tříd výjimek v jednom catch bloku - jedna třída výjimek v sobě zahrnuje i všechny potomky této třídy. Protože však u záchytných bloků záleží na pořadí, (2) je možné některé potomky zachytit zvlášť a ostatní nechat bloku zachycující výjimky rodičovské třídy:
Programátor si samozřejmě může vytvořit vlastní třídu výjimek - stačí vytvořit potomka některé z tříd výjimek z Java Core API (nedoporučuje se však jako rodičovskou třídu použít přímo Throwable). 13.2. Vyvolání výjimkyVýjimky je možné programově vyvolávat příkazem throw. Jeho syntaxe je:
throw instanceVýjimky ; Výjimka instanceVýjimky musí být instancí třídy Throwable nebo jejích potomků.
13.3. Deklarace výjimekVšechny výjimky, které mohou v dané metodě nastat, musí být zachyceny nebo deklarovány (viz 11.2.2.), jinak překladač ohlásí chybu. (3) Druhý případ znamená, že metoda přenechává ošetření deklarovaných výjimek volající metodě - dochází k tzv. propagaci výjimek (viz 13.4.). Volající metoda opět musí tyto (resp. všechny) výjimky zachytit nebo deklarovat.Deklarace výjimek se používá zejména v případě, že na dané úrovni (např. přímo v knihovně) není vhodné provádět ošetření výjimky (není možné rozhodnout, jak by mělo vypadat ošetření):
13.4. Propagace výjimekVýjimka může být uvnitř metody vyvolána dvěma způsoby:Pokud není vyvolaná výjimka zachycena blokem catch (viz str. 13) v metodě, kde byla vyvolána, je předána o úroveň výš (volající metodě). Takto se výjimka rekurzivně předává dokud nedojde k jejímu zachycení a v krajním případě je zachycena runtime systémem, který zachycuje všechny výjimky (standardně vypíše chybovou zprávu a ukončí program). Tento mechanismus se nazývá propagace výjimek.
13.5. Runtime výjimkyZvláštní postavení mezi výjimkami mají tzv. runtime výjimky - instance třídy RuntimeException a jejích potomků. Tyto výjimky nemusí být v metodách zachycovány ani deklarovány.Runtime výjimky totiž reprezentují chyby, které mohou nastat "kdekoliv" v programu. Jedná se například o ArrayIndexOutOfBoundsException (přetečení indexu pole) nebo ArithmeticException (aritmetická chyba - celočíselné dělení nulou) apod. Ošetřování těchto výjimek by mnohdy znamenalo zbytečnou práci navíc, neboť například ve for cyklu lze snadno zajistit, aby index pole meze nepřekročil. Pokud by ArrayIndexOutOfBoundsException nebyla runtime výjimkou, bylo by ji nutné v každé metodě, která pole používá zachytit nebo deklarovat. 13.6. Koncový blok (finally)Dvojici bloků try - catch (viz str. 13) je možné rozšířit o nepovinný koncový blok finally následovně:
try { // hlídaný blok } catch( třídaVýjimek1 jménoProměnné1 ) { // ošetření výjimky } finally { // zde uzavřený kód se provede vždy } Koncovým blokem program pokračuje po ukončení hlídaného i záchytného bloku (tj. ať už výjimka nastane nebo ne). Koncový blok se vykoná dokonce i v případě, že:
|