Vaše jistota na trhu IT Výjimky Rudolf Pecinovský [email protected] Vaše jistota na trhu IT Obsah s odkazy ►Výjimky ►Výjimky kontrolované a nekontrolované ►Definice vlastních výjimek Vaše jistota na trhu.

Download Report

Transcript Vaše jistota na trhu IT Výjimky Rudolf Pecinovský [email protected] Vaše jistota na trhu IT Obsah s odkazy ►Výjimky ►Výjimky kontrolované a nekontrolované ►Definice vlastních výjimek Vaše jistota na trhu.

Slide 1

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 2

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 3

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 4

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 5

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 6

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 7

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 8

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 9

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 10

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 11

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 12

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 13

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 14

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 15

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 16

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 17

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 18

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 19

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 20

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 21

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 22

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 23

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 24

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 25

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 26

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 27

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 28

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 29

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 30

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 31

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600


Slide 32

Vaše jistota na trhu IT

Výjimky
Rudolf Pecinovský
[email protected]

Vaše jistota na trhu IT

Obsah s odkazy
►Výjimky
►Výjimky kontrolované a nekontrolované

►Definice vlastních výjimek

Vaše jistota na trhu IT

Výjimky
►Výjimečné situace v programech

►Ošetření nestandardních situací v Javě
►Zpráva o výjimce
►Klíčová slova

►Činnost
►Vyvolání

Výjimečné situace v programech
► V každém programu je alespoň jedna chyba –
program na ni musí být připraven
► Starší programy

● Program vypsal chybové hlášení a ukončil činnost;
● V některých situacích (válcovací stolice, autopilot, …) nepřijatelné

● Funkce vrátí hodnotu signalizující chybu

● Programátor musí neustále testovat, co funkce vrací

● Knihovna měla pro tyto účely vyhrazenu speciální proměnnou,

do níž se v případě chyby zapsal její kód; nahlédnutím do proměnné
program zjistil kód poslední chyby
● Programátor musí neustále testovat, jaká je v proměnné hodnota

► Některé jazyky (Cobol, PL/1, …) proto přišly s koncepcí
ošetření nestandardních situací

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

4

Ošetření nestandardních situací v Javě
► Výjimečná událost =
problém, který brání dalšímu vykonávání části kódu
► Událost je výjimečná v tom, že na rozdíl od běžných problémů
nemá program k vyřešení situace dost informaci
► Program může při výskytu výjimečné události vyvolat výjimku

► Výjimka (exception)
objekt určený k přenosu informací o nastalém problému
z místa jeho vzniku do místa, kde bude problém řešen

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

5

Postup při vyvolání výjimky
1. Vytvoří se výjimka = objekt typu Throwable
(prakticky vždy instance některého z potomků)
2. Vytvořená výjimka se vyhodí =
přeruší se běh programu v místě, kde výjimka vznikla,
a začne se hledat místo, kde bude daná výjimka ošetřena
3. Ošetření výjimky (handler) by mělo uvést program do stavu,
v němž může jeho vykonávání pokračovat
► Výjimka „probublává“ programem z místa vyhození stále výše
a nenarazí-li cestou nikde na své ošetření,
zachytí ji virtuální stroj, který na standardní chybový výstup
vypíše zprávu o vzniku výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

6

Systémová zpráva o vzniku výjimky
Zpráva o vzniku výjimky spolu s názvem vlákna,
v němž k výjimce došlo (zde AWT-EventQueue-0)

Popis druhu výjimky (aritmetická výjimka dělení nulou)

Informace o místě, odkud byla volána metoda,
která vyvolala metodu, v níž došlo k vyhození výjimky
Informace o místě, odkud byla volána metoda,
v níž došlo k vyhození výjimky
Úplný název třídy včetně balíčku
Copyright © 2006, Rudolf Pecinovský

Název metody
VŠE – 05

Název souboru se
zdrojovým kódem
Číslo řádku zdrojáku,
kde došlo k výjimce
7

Klíčová slova související s výjimkami
► try (zkus)
Označuje blok kódu, v němž může dojít k výjimce
► throw (hoď)
Příkaz k vyhození výjimky;
musí být následován odkazem na existující instanci
► catch (chyť)
Blok ošetřující výjimku, která je zadána jako parametr
► finally (na konec)
Blok s povinnými závěrečnými akcemi nezávisejícími
na případném vzniku výjimky
► throws (hází)
Uvození seznamu výjimek vyhazovaných danou metodou

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

8

Vyvolání a ošetření výjimky v kódu
try {
//Kód, který může vyvolat výjimky
}
catch( Typ1 id1 ) {
//Ošetření výjimek typu Typ1
}
...
catch( TypN idN ) {
//ošetření výjimek typu TypN
}
finally {
//Kód, který se na závěr VŽDY provede
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

9

Náznak činnosti – řádný průběh
nedojde k vyvolání výjimky
= nedojde k chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

12

Náznak činnosti – ošetřený výjimka
try {
příkaz1(); Při provádění metody příkaz2
dojde k ošetřené chybě
příkaz2();
příkaz3();
Byla vyhozena výjimka
tohoto typu nebo typu
}
některého z potomků
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ostatní bloky catch
catch (…..
se přeskočí
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

13

Náznak činnosti – neošetřená výjimka
Při provádění metody příkaz2
dojde k NEošetřené chybě

try {
příkaz1();
příkaz2();
příkaz3();
}
catch ( xxxException e ) {
příkazProOšetřeníChyby();
}
Ošetření nebylo nalezeno =>
catch (…..
provede se blok finally
a opouští se metoda
finally {
ukončovacíPříkazy();
}
dalšíPříkaz();

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

14

Vyvolání výjimky
public class Xyz implements Comparable
{
public bolean compareTo( Object o )
{
if( !(o instanceOf Xyz) )
throw new ClassCastException (
"\nPokus o porovnání s neporovnatelnou"
+ " instancí " + o );
//Zjištění, kdo je větší
return vysledek;
}
}

► Instanci nemusíme vytvářet až v příkazu throw,
můžeme ji vytvořit kdykoliv před tím a pak mu ji jen předat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

15

Vaše jistota na trhu IT

Výjimky kontrolované a
nekontrolované
►Hierarchie výjimek
►Pořadí výjimek v blocích catch
►Metody generující výjimky
►Metody třídy Throwable

►Zřetězené výjimky
►Převod kontrolovaných na nekontrolované

Charakteristika
► Výjimky, které jsou potomky třídy RuntimeException
nebo Error označujeme jako nekontrolované (unchecked),
protože překladač nekontroluje, zda je na ně program připraven
► Ostatní výjimky označujeme jako kontrolované (checked),
protože překladač kontroluje dodržení pravidel:

● Každá metoda, která může vyhodit kontrolovanou výjimku,

se musí k této skutečnosti veřejně přihlásit
● Každé použití metody, která může vyhodit kontrolovanou výjimku,
musí být buď uzavřeno v bloku try…catch,
nebo se volající metoda musí přihlásit k tomu,
že může také vyhodit danou kontrolovanou výjimku

► Nekontrolované výjimky ohlašují chyby v programu,
kontrolované výjimky očekávatelné situace,
na jejichž výskyt má být program připraven
a měl by na ně umět reagovat
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

17

Hierarchie výjimek

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

18

Pořadí výjimek v blocích catch
► Třída NumberFormatException
je potomkem třídy RuntimeException
try {
Syntaktická chyba,
......
na druhý blok catch nikdy nedojde
}
catch (RuntimeException e) {
.........
}
Obrácené pořadí bloků catch
catch (NumberFormatException e){
vše vyřeší
........
try {
}
......
}
catch (NumberFormatException e) {
.........
}
catch (RuntimeException e){
........
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

19

Metody generující výjimky
► Java vyžaduje, aby programy, které používají metody
schopné vyvolat kontrolované výjimky,
byly o této schopnosti používaných metod informovány =>
pak vědí, které výjimku musí umět zachytit a ošetřit
► Všechny kontrolované výjimky, které může metoda vyhodit,
musí deklarovat v hlavičce za klíčovým slovem throws
► Deklarace vyhazování nekontrolovaných výjimek není povinná
public void metoda()
throws KontrolovanáVýjimka1,
KontrolovanáVýjimka2
{
// Tělo metody
}
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

20

Metody třídy Throwable
► String getMessage()
Vrátí zprávu popisující danou výjimku
► String toString()
Vrátí název třídy výjimky následovaný případnou zprávou
► void printStackTrace()
Vytiskne toString() následovaný sadou informací o volající
posloupnosti, která vedla k vzniku výjimky
► Throwable fillInStackTrace()
Připraví nové informace o volací posloupnosti
vedoucí k místu zavolání této metody
► StackTraceElement[] getStackTrace()
Vrátí uchované informace o volací posloupnosti dané výjimky

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

21

Zřetězené výjimky
► V některých situacích je vhodné v rámci ošetření výjimky vyvolat
jinou výjimku, a přitom umožnit zjistit,
která výjimka byla prvotním hybatelem celé akce
► Řada výjimek má mezi svými konstruktory i takové,
které akceptují jako poslední parametr
odkaz na výjimku, jež byla příčinou vyvolání dané výjimky
► Chce-li se program zeptat výjimky na výjimku, která ji způsobila,
použije metodu
public Throwable getCause()

► Ve zprávě o vyvolání výjimky jsou místa, kde byla jedna výjimka
nahrazena jinou, označována textem caused by:

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

22

Ukázka výpisu při zřetězení výjimek
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

23

Převod kontrolovaných na nekontrolované
► Ošetřování kontrolovaných výjimek obtěžuje
► Víme-li, že k dané výjimce nejspíš nedojde
a ošetřujeme-li ji pouze proto, že na tom překladač trvá,
můžeme pro případ, že by k výjimce přece jenom došlo
zaměnit kontrolovanou výjimku za nekontrolovanou
public void prevod( String s ) {
try {
prověř( s );
} catch( Exception ex ) {
throw new RuntimeException( " Neprověřeno! ", ex );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

24

Vaše jistota na trhu IT

Definice vlastních výjimek
►Hierarchie výjimek
►Pořadí výjimek v blocích catch

►Metody generující výjimky
►Metody třídy Throwable
►Vlastní výjimky
►Zásady správného používání výjimek

Definice vlastních výjimek
► Výjimky jsou zcela běžné třídy;
považujeme-li to proto za vhodné, můžeme definovat i vlastní
► Před definicí nové výjimky bychom si měli ujasnit,
bude-li kontrolovaná či nekontrolovaná;
podle toho definujeme jejího předka
► Název výjimek končí dle konvencí slovem Exception
před nímž je naznačena podstata dané výjimky

● IllegalArgumetnException
● NoSuchMethodException
● BadStringOperationException

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

26

Příklad vlastní kontrolované výjimky
public class VelkýPrůšvihException
extends Exception
{
public VelkýPrůšvihException() {};
public VelkýPrůšvihException( String zpráva ) {
super( zpráva );
}
public VelkýPrůšvihException(String zpráva,
Throwable původce ) {
super( zpráva, původce );
}
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

27

Test správného vyhození výjimky
► Na vytvářených programech je třeba otestovat i to,
že v definovaných situacích vyhodí požadovanou výjimku
public void testVyhozeníVýjimky()
{
try {
metodaKteráMáVyhoditVýjimku();
} catch ( VelkýPrůšvihException vpe ) {
return;
}
fail( "Nebyla vyhozena výjimka VelkýPrůšvihException" );
}

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

28

Zásady správného používání výjimek

1/2

Neignorujte
výjimky

try {
//Nějaký kód
}
catch(Exception e){}

► Výjimky, o nichž víte, že nemohou nastat,
převeďte na nekontrolované pro případ,
že by v budoucích verzích programu nastat mohly
► Při ošetřování výjimek, které nastat mohou,
ale nemají vliv na chod programu,
vložte do těla ošetření alespoň vysvětlující komentář
Copyright © 2006, Rudolf Pecinovský

VŠE – 05

29

Zásady správného používání výjimek

2/2

► Používejte výjimky pouze k ošetření výjimečných stavů
► Kontrolované výjimky používejte u stavů, z nichž se lze zotavit,
jinak použijte výjimky nekontrolované

► Vyhýbejte se zbytečnému používání kontrolovaných výjimek

● Programátory ošetřování kontrolovaných výjimek obtěžuje
a mají pak tendenci je ošetřovat prázdným blokem catch

► Dávejte přednost standardním výjimkám,
vyvolávejte výjimky odpovídající dané abstrakci

● Programátoři by měli z názvu výjimky poznat, co se stalo
● Standardní výjimky mají všeobecně známý význam

► Snažte se o atomičnost selhání; i po vyhození výjimky
by měl být objekt v dobře definovaném stavu

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

30

Zásady správného používání výjimek

3/2

► Doplňujte výjimky zprávami,
výjimka by sama měla poskytnout dostatek informací
a neměla by programátora nutit k podrobnější analýze programu
► Dokumentujte vyvolávané výjimky v dokumentačních
komentářích pomocí značky @throws
► Nedělejte bloky try zbytečně velké,
kód uvnitř těchto bloků se neoptimalizuje

► Umíte-li výjimku v metodě ošetřit, udělejte to
► Detekuje-li se chyba v jedné metodě a má se ošetřit v jiné
(stejné či jiné instance), použijte výjimku.

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

31

Nejčastěji používané výjimky

1/2

► IllegalArgumentException
Byla zadána nepovolená hodnota parametru

● Např. chci nastavit zápornou velikost grafického tvaru

► IllegalStateException
V daném stavu objektu nelze metodu provést

● Např. otevřu soubor, přečtu pár vět, zavřu soubor a chci znovu přečíst větu

► NullPointerException
Byla vyvolána metoda instance, na níž ukazuje prázdný odkaz,
nebo byl předán nepovolený prázdný odkaz v parametru
► ArrayIndexOutOfBoundException
Byly zadány špatné meze pole, buď záporné nebo moc velké

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

32

Nejčastěji používané výjimky

2/2

► ConcurrentModificationException
V průběhu iterace byla změněna struktura kontejneru

● Např. byl do kontejneru přidán prvek

► NumberFormatException
Je požadován špatný převod řetězce na číslo či naopak

● Chci-li např. převést na číslo řetězec, který není číslem
● Častá chyba v metodách String.format či PrintStream.printf

► ClassCastException
Požadované přetypování není možné
► UnsupportedOperationException
Požadovaná operace není podporována
(např. chci přidat prvek do neměnného kontejneru)

Copyright © 2006, Rudolf Pecinovský

VŠE – 05

33

Vaše jistota na trhu IT

Děkuji za pozornost

►Rudolf Pecinovský
http://vyuka.pecinovsky.cz/vse
mail: [email protected]
ICQ: 158 156 600