Nedaří se mi rychle najít, jak to bude se zachycením výjimek při volání AutoCloseable.close()
. Bude to v některém z příštích dílů?
Z příkladů v článku je patrné, co se stane v případě, když dojde k vyvolání výjimky i v bloku try {…}
– výjimky z AutoCloseable.close()
se k té výjimce přidají jako odložené, a je pak možné si je přečíst z Throwable.getSuppressedExceptions()
(nebo se vypíšou při výpisu zásobníku volání). Ale co v případě, kdy v bloku try {…}
k výjimce nedojde, ale dojde k jedné (nebo více) výjimkám v AutoCloseable.close()
? Vyhodí se poslední výjimka z close()
, a k ní jsou případně přidány jako odložené výjimky z předchozích close()
?
A jak se to bude chovat v případě, že k vyhození výjimky dojde v bloku finally {…}
– stejně jako s try
, tj. vyhozena bude výjimka z finally {…}
a k ní budou jako odložené přidány výjimky z volání close()
? A co v případě, kdy bude výjimka vyhozena v try {…}
i finally {…}
– výjimka z try
se zahodí (jako dnes) a propaguje se jen ta z finally
s vloženými potlačenými výjimkami, nebo se i ta z try
přidá mezi potlačené? To by pak změnilo i význam kódu pro 1.6 přeloženého 1.7 kompilátorem, i když by ta změna neměla mít žádný viditelný dopad…
Vy pisete nejaky komplikovany kod. Mozno by sa niekedy hodili ale tie si mozete urobit pomocou standardneho kodu bez Closeable. Ale na 99% veci potrebujete v podstate jednoduchy handling. Nieco robim a to bud skonci OK alebo s chybou ktoru oznamym operatorovi (do logu) a skoncim.
Veci ako opakovanie operacie po N minutach a podobne sa riesia na vyssej urovni ako try/catch blok.
Uniká mi souvislost vašeho komentáře s tím mým. Já jsem neuváděl žádný příklad kódu, ptal jsem se, jak je ve standardu nadefinováno chování toho rozšířeného příkazu try
. V článku autor poukázal na to, že může v kódu vzniknout paralelně několik výjimek, a je tam uveden příklad, jak se to řeší v určitém případě – a já jsem se zeptal na ostatní případy. Do Javy 1.6 mohlo několik výjimek „najednou“ vzniknout jen vyhozením výjimky ve finally a platilo pravidlo „poslední vyhrává“. V Javě 1.7 se tohle evidentně změní, tak jsem se jen ptal, zda Pavel Tišnovský (nebo někdo jiný) náhodou neví detaily.
Je to vyresene tak, ze cely "novy" blok try, tj. blok s deklaracni casti, muze vyhodit az _n_+1 vyjimek, kde _n_ je pocet objektu vytvarenych v deklaracni casti bloku try, tj. za kulatymi zavorkami (a nic jineho v teto casti bloku byt nesmi).
Presneji - jednu vyjimku muze vyhodit telo bloku try, coz je logicke a dalsich _n_ vyjimek muze vyhodit metoda close() - ta mimochodem je definovana tak, ze vyhazuje vyjimku typu Exception ne IOException, to jsem zapomel v clanku zminit.
Seznam vyhozenych vyjimek se v catch() da zjistit pomoci getSuppressedExceptions() a navic se printStackTrace() chova ponekud jinak - vypise vsechny vyhozene vyjimky s prefixem suppressed. Je to v clanku uvedeno, prozatim bez vetsiho komentare, protoze se mozna jeste bude format menit.
Ano, chybové stavy každého otravují, proto mívají aplikace centrální exception handler, který se o to stará.
Myšlenka checked exceptions nebyla špatná, jen se postupem vývoje ukázalo, že je zbytečně paranoidní. Unchecked exceptions stačí, jako v C#.
A k té druhé části - možná by vám ještě víc chránilo kejhák to, kdybyste všude psal 'catch (NullPointerException npe) {...}' :-)
To je ovsem pusta teorie. Pokud mate dotaz na DB jako "SELEKT * FORM tabule", tak to je chyba programatora (2 preklepy) a vyjimka je stejna jako kdyz zdechne DB server. To by az tak nevadilo, ale checkovany vyjimky mnohem vic prudi nez pomahaji. Myslenka je to dobra, ale nedotazena, coz je videt uz na prikladu toho Closeable. Namisto dopisovani throws klausuli by to chtelo statickou analyzu celeho kodu s moznosti deklarovat vyjimky mimo kod tridy, tim by se daly podchytit i nektery RuntimeException-s.