Výjimky (exceptions)

Proč to potřebuji?

Žádný program není bez chyb. Výjimky poskytují strukturovaný mechanismus pro zachycení a zpracování chybových stavů za běhu, což vede k robustnějším a spolehlivějším aplikacím.

Teorie

Výjimky řeší chybové stavy za běhu programu. Hierarchie: ThrowableError (fatální) a Exception.

Kontrolované (checked) výjimky – dědí z Exception, musí být zachyceny nebo deklarovány v throws. Příklad: IOException.

Nekontrolované (unchecked / runtime) výjimky – dědí z RuntimeException, nemusí být deklarovány. Příklad: NullPointerException, IndexOutOfBoundsException.

Příklady

// Vlastní kontrolovaná výjimka
public class NedostatekPenezException extends Exception {
    private double chybejici;

    public NedostatekPenezException(double chybejici) {
        super("Chybí " + chybejici + " Kč");
        this.chybejici = chybejici;
    }

    public double getChybejici() {
        return chybejici;
    }
}

// Použití výjimek
public class Ucet {
    private double zustatek;

    public Ucet(double zustatek) {
        this.zustatek = zustatek;
    }

    // throws – deklarace kontrolované výjimky (propagace)
    public void vyber(double castka) throws NedostatekPenezException {
        if (castka <= 0) {
            // Nekontrolovaná výjimka – chyba programátora
            throw new IllegalArgumentException("Částka musí být kladná");
        }
        if (castka > zustatek) {
            // Kontrolovaná výjimka – očekávaný chybový stav
            throw new NedostatekPenezException(castka - zustatek);
        }
        zustatek -= castka;
    }
}

// Zachycení a zpracování
public static void main(String[] args) {
    Ucet ucet = new Ucet(1000);

    try {
        ucet.vyber(1500);
    } catch (NedostatekPenezException e) {
        System.out.println("Nelze vybrat: " + e.getMessage());
        System.out.println("Chybí: " + e.getChybejici() + " Kč");
    } finally {
        // Provede se VŽDY – uvolnění zdrojů
        System.out.println("Operace dokončena.");
    }

    // Try-with-resources (automatické zavření)
    try (var reader = new BufferedReader(new FileReader("data.txt"))) {
        String radek = reader.readLine();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // reader je automaticky zavřen
}

Shrnutí

Klíčové body

  • Checked výjimky: musí být v catch nebo throws
  • Unchecked (RuntimeException): nemusí být deklarovány
  • try-catch-finally – zachycení, throw – vyhození, throws – deklarace
  • try-with-resources automaticky zavírá zdroje implementující AutoCloseable