if (x <= 0) {
throw new IllegalArgumentException("x was expected to be positive");
}
Výjimky jsou mechanizmem umožňujícím reagovat na nestandardní (tj. chybové) běhové chování programu, které může mít různé příčiny:
Proč výjimky?
Výjimky v Javě fungují podobně jako v dalších objektových jazycích (C++, Python). |
Exception
je objektem třídy (nebo podtřídy) java.lang.Exception
.Constructor | Description |
---|---|
NullPointerException() |
Constructs a NullPointerException with no detail message. |
NullPointerException(String s) |
Constructs a NullPointerException with the specified detail message. |
Preferujeme konstruktor se zprávou. |
Objekt výjimky je vyhozen:
samotným programem použitím klíčového slova throw
, zdetekuje-li nějaký chybový stav, na nějž je třeba reagovat
if (x <= 0) {
throw new IllegalArgumentException("x was expected to be positive");
}
Vyhozený objekt výjimky je buďto:
catch
).
Výjimka propadne do nadřazené (volající) metody, kde je buďto v bloku catch
zachycena nebo opět propadne atd.
Proto existuje mechanismus try-catch
bloku, který umožňuje reagovat na vyhození výjimky.
try
blok vymezující místo, kde může výjimka vzniknout
catch
blok, který se vykoná, nastane-li výjimka odpovídajícího typu
catch
výjimku zachytí.catch
bloku:try {
throw new NullPointerException();
} catch(NullPointerException e) {
System.out.println("NPE was thrown and I caught it");
}
int[] array = new int[] { 16, 25 };
try {
int x = array[2];
} catch(ArrayIndexOutOfBoundsException e) {
System.err.println("Only index 0 or 1 can be used");
}
Jak funguje try
blok?
try
se přeskočí a kontroluje se catch
blokcatch
se ignorují
Jak funguje catch
blok?
catch(ExceptionType variableName) { … }
catch
blokucatch
bloků může být víc, pak se prochází postupněcatch
blokcatch
blokytry {
String s = null;
s.toString(); // NPE exception is thrown
s = "This will be skipped";
} catch(IllegalArgumentException iae) {
System.err.println("This will not be called");
} catch(NullPointerException npe) {
System.err.println("THIS WILL BE CALLED");
} catch(ArrayIndexOutOfBoundsException e) {
System.err.println("This entire block will be skipped");
}
catch
try {
new Long("xyz");
} catch (NumberFormatException e) {
System.err.println(e.getMessage());
}
catch
blokůtry {
Person p = new Person(null);
} catch(NullPointerException e) {
System.err.println("Invalid name.");
} catch(IllegalArgumentException e) {
System.err.println("Invalid name.");
}
Operátor |
sloučí stejné catch
bloky:
try { ... }
catch(NullPointerException | IllegalArgumentException e) {
System.err.println("Invalid name.");
}
Jak můžeme na vyhozenou výjimku reagovat?
Oracle Java Tutorials: Lesson: Handling Errors with Exceptions |
catch
catch
řetězíme, musíme respektovat, že výjimka bude zachycena nejbližším příhodným catch
.try {
...
} catch (Exception e) {
...
} catch (IllegalArgumentException e) {
// won't compile, unreachable code
}
Výjimka z podtřídy (speciálnější) musí být zachycována dříve než výjimka obecnější. |
try {
...
} catch ( Exception e ) {
...
}
Problém: Zachytávame všechny výjimky, některé výjimky ale vždy chceme propouštět.
Řešení:
Použít v catch
speciálnější typ třídy.
try {
...
} catch ( NullPointerException e ) {
}
Problém:
Prázdny catch
blok — nedozvíme se, že výjimka byla vyhozena.
Řešení:
Logovat, vypsat na chybový výstup nebo použít e.printStackTrace();
try {
throw new NoSuchMethodException();
} catch ( NoSuchMethodException e ) {
throw e;
}
Problém: Kód zachytí a následně vyhodí stejnou výjimku.
Řešení:
Blok catch
smazat — je zbytečný.
/