W tym wpisie pokażę jak można przechwytywać wiele wyjątków naraz, gdy chcemy je obsługiwać w ten sam sposób. Jest to tak zwany multicatch i jest on dostępny również w Javie, począwszy od wersji 7.
Za przykład niech posłuży nam sytuacja, w której dana metoda może rzucić jednym z wielu wyjątków, na przykład:
public void businessMethod() throws IOException, IllegalStateException, BusinessException{
gdzie BusinessException
jest zdefiniowany w następujący sposób:
public BusinessException() extends IllegalStateException() { public BusinessException(String msg) { super(msg); } }
Multicatch przed Javą 7
Po użyciu tej metody musimy obsłużyć wszystkie trzy wyjątki i potrzebujemy osobny blok catch
dla każdego z nich:
try { businessMethod() } catch (IOException ex) { System.out.println(ex.getMessage()); } catch (BusinessException ex) { System.out.println(ex.getMessage()); } catch (IllegalStateException ex) { System.out.println(ex.getMessage()); }
W tym wypadku należy również pamiętać by obsłużyć wszystkie wyjątki w odpowiedniej kolejności, a konkretniej by obsłużyć BusinessException
przed IllegalStateException
. Jest to spowodowane faktem, że nasz własny wyjątek dziedziczy po IllegalStateException
i gdyby był w kolejności po nim, to wtedy (jako że każdy BusinessException
jest typu IllegalStateException
), nigdy nie dochodziłoby do obsługi naszego wyjątku, ponieważ wszystko byłoby łapane w bloku catch IllegalStateException
.
Multicatch i Java 7+
W Javie od wersji 7 w górę możemy zmniejszyć ilość bloków catch
, jeśli chcemy obsłużyć wiele różnych wyjątków w ten sam sposób – służy do tego tak zwany mulitcatch:
try { businessMethod() } catch (BusinessException ex) { System.out.println(ex.getMessage()); } catch (IllegalStateException | IOException ex) { System.out.println(ex.getMessage()); }
Dzięki temu skraca nam się nieco składnia – wyjątki rozdzielamy znakiem |
. Jednak i tu należy uważać na kwestie dotyczące dziedziczenia i hierarchii wyjątków. Ponownie BusinessException
jest „problematyczny” – nie może się on znaleźć w tym samym bloku multicatch
co jego rodzic – czyli IllegalStateException
, wciąż musi być on obsługiwany w osobnym bloku.
Drugą różnicą, już mniej dotkliwą, jest kwestia „przepakowania” parametru ex
. W „starej” Javie mogliśmy zrobić coś takiego:
catch (IOException ex) { ex = new IOException("new message"); }
W nowszych wersjach, przy użyciu mulitcatch, nie jest to już możliwe – parametr ex
jest niejawnie typu final
.
Podsumowanie
I to by było na tyle jeżeli chodzi o temat multicatch w Javie. Na pewno warto pamiętać, że mamy takie narzędzie do dyspozycji (w zależności od tego z jakiej wersji Javy akurat korzystamy w projekcie). Natomiast korzystając już z multicatcha oraz pracując z wyjątkami, które sami utworzyliśmy, nie zapominajmy o hierarchii dziedziczenia.