2.7.2. Příkaz try-catch

Zpracování výjimky se vždy vztahuje k bloku programu omezenému příkazem try následovaném jedním nebo více bloky catch popisujícími způsob ošetření jednotlivých výjimek. Například chceme-li ošetřit chyby při práci se souborem, můžeme postupovat takto:

InputStream fs = null; 
try { 
   fs = new FileInputStream("data.txt"); 
} catch( FileNotFoundException e ) { 
   System.err.println("Soubor data.txt nenalezen"); 
   System.exit(2); 
}   

Nastane-li kdykoliv během zpracování těla příkazu try výjimka FileNotFoundException (definovaná stejně jako třídy InputStream a FileInputStream v balíku java.io), výpočet těla se ukončí a přejde se do odpovídajícího bloku catch. Tam se vypíše chybová zpráva a běh programu se ukončí s návratovým kódem 2.

V bloku catch může být místo konkrétní třídy výjimky rovněž uvedena některá nadtřída zahrnující celou skupinu výjimek. Například pro ošetření libovolné chyby v operacích vstupu a výstupu můžeme použít zápisu

try { 
   . . . 
} catch( IOException e ) { 
   System.err.println(e); 
   System.exit(2); 
}
kde po zachycení výjimky, která je instancí libovolné podtřídy IOException, se vypíše popis výjimky a program se ukončí. V místě ošetření výjimky můžeme rovněž zavolat metodu výjimky printStackTrace(), zděděnou z třídy Exception. Ta vypíše obsah programového zásobníku v okamžiku vzniku výjimky, z něhož můžeme získat další informace o místě a příčinách vzniku výjimky.

Příklad 2.5.
Vytvořte program, který vypíše na standardní výstup čísla od 1 do hodnoty zadané na příkazovém řádku.

Metoda main() získá hodnotu z příkazového řádku jako prvek pole řetězců args s indexem 0 (pozor - pokud jste zvyklí na jazyk C/C++, tak Java na pozici 0 nedostává jméno programu, ale skutečně již první argument). Při řešení této úlohy musíme nejprve převést zadanou hodnotu z řetězce na číslo. To nám spolehlivě provede metoda parseInt() třídy Integer. Ovšem pokud se podíváte do dokumentace, tak zjistíte, že metoda parseInt() může po zadání chybně vytvořeného čísla způsobit výjimku NumberFormatException, kterou tedy musíme správně ošetřit.

class TiskCisel { 
   public static void main(String[] args) { 
      try { 
         int n = Integer.parseInt(args[0]); 
         for(int i = 1; i <= n; i++) 
            System.out.println(i); 
      } catch( NumberFormatException e ) { 
         System.err.println("Chyba: Nespravny format argumentu"); 
      } 
   } 
}

Vyzkoušíte-li si tento program a vyvoláte ho např. příkazem

java TiskCisel 10
dostanete řadu čísel od 1 do 10. Zadáte-li jako argument např. řetězec abc, vypíše program chybové hlášení. Co se ale stane, jestliže nezadáte žádný argument? V tom případě bude pole args prázdné a při odkazu na prvek args[0] vznikne výjimka s dostatečně výmluvným názvem ArrayIndexOutOfBoundsException, kterou jsme ale neošetřili. A ani ji ošetřovat nebudeme, raději ještě na začátku programu zkontrolujeme, zda seznam parametrů něco obsahuje, a pokud ne, vypíšeme jako u většiny slušných programů návod k použití:
if( args.length == 0 ) { 
   System.err.println("Navod: Zadejte pocet vypisovanych cisel"); 
   System.exit(0); 
}