10. seminář - Výjimky + Optional

TEACHINGJJ2

Výjimky

  • Výjimky v Java tutoriálu.
  • Událost signalizující, že výpočet neprobíhal tak, jak bylo zamýšleno.
  • Přeruší výpočet a oznámí to volajícímu - ten může na situaci nějak reagovat, nebo přerušit svůj výpočet a oznámit to volajícímu atd.
  • Příklad, soubor neexistuje, nebo nemáme právo zápisu; uživatelský vstup je neplatný; někdo zkoušel dělit nulou…
  • Potomci třídy Exception. (Existuje i obecnější Throwable.)
  • Error (kritické chyby) vs RuntimeException (programátorské chyby) vs Exception (neplatné stavy, na které má smysl reagovat)
  • Ukázka použití.

Checked vs unchecked

  • Checked exceptions - výjimky, které jsou součástí API balíčku/metod - klíčové slovo throws v hlavičce metody.
  • Unchecked exceptions - výjimky, které v API být nemusí (RuntimeException, Error a jejich potomci). Typicky vážné věci, na které uživatel stejně nemá jak reagovat. Mohou být vyvolány kdekoliv. Např. IndexOutOfBoundsException, NullPointerException, …, VirtualMachineError, ThreadDeath, AssertionError, …
  • Kdy použít který typ? Záleží na situaci…
  • Poučka: “Pokud s tím volající může něco udělat, použijeme checked exception, ať může reagovat. Pokud je to stav, na který se rozumně reagovat nedá, tak použijte některou z unchecked exceptions.”

Optional

  • Dokumentace
  • Všeříkající citace: “Optional is primarily intended for use as a method return type where there is a clear need to represent”no result,” and where using null is likely to cause errors. A variable whose type is Optional should never itself be null; it should always point to an Optional instance.”
  • Jinými slovy pokud z metody může vypadnout null a pokud to nejspíš bude problém, tak můžeme místo typu T vracet typ Optional<T> a tím si “vyžádat” kontrolu vrácené hodnoty ze strany volajícího.
  • Zajímavá je i poslední věta - není dobrý nápad dát do Optional proměnné null, byť technicky to možné je.
  • Ukázka

Úkoly

Rozšiřte/upravte úkol č. 4 z předminulého semináře (RPN kalkulačku), tj. metodu rpnCalc(String expr, Map <String, Object> variables) o následující vlastnosti:

  • Metoda by měla umět vyhodnocovat výrazy s celými čísly (např. 1, 12, -123) i s čísly s plovoucí řádovou čárkou (např. 1.0, 2.23, 45.56, -78.123). Pokud dojde k sečtení (odečtení, atd.) dvou čísel, kde jedno je číslo s plovoucí řádovou čárkou, výsledkem je číslo s plovoucí řádovou čárkou.
    1.1 2 +    --> 3.1
    1 2 +      --> 3
    
  • Přidejte podporu pravdivostních hodnot reprezentovaných literály (#t, #f) a přidejte operátory <, > =, !=, <=, >=, porovnávající čísla a pravdivostní hodnoty. Pokud hodnoty nejde porovnat, skončí metoda vyjímkou.
    1.1 2 <    --> #t
    #f #t <    --> #t
    #f #t >    --> #f
    1 #f =     --> Exception -- Neporovnatelne hodnoty
    
  • Přidejte ternární operátor "?", který odebere z vrcholu zásobníku pravdivostní hodnotu a dvě další hodnoty. Pokud byla na vrcholu zásobníku hodnota #t, vrátí druhou odebranou hodnotu, jinak vrátí třetí. Pokud na vrcholu zásobníku nebude pravdivostní hodnota, skončí metoda vyjímkou.
  • 1 2 3 4 < ?    --> 2
    1 2 3 4 + ?    --> Exception -- 7 neni pravdivostni hodnota
    
  • Program napište tak, aby adekvátně ošetřil i další chybové stavy, např. dělení nulou, špatně zapsaný výraz, atd.
  • Program napište tak, aby nebyl realizován jako jedna metoda a byl řádně rozčleněn a dokumentován.
Napište nasledující metody pro parsování celého a desetinného čísla y řetězce. Při řešení nepoužívejte metody Integer.parseInt() a Double.parseDouble().

    public static Optional<Integer> parseInt(String string)
    public static Optional<Double> parseDouble(String string)