
Czym blok finally jest wykonywany w przypadku złapania wyjątku?
W przypadku, gdy mamy blok try catch możemy dodać kolejny blok finally, który powinnien wykonywać się zawsze. Jednak czy na pewno jest to prawda? Co w przypadku, gdy złapiemy wyjątek lub zwrócimy wartość z metody już w bloku try?
Przetestujmy to na prostych przykładach:
package pl.rekrutacja.pytanie; public class Main { public static void main(String[] args) { try { divideWithCatch(1, 0); } catch (ArithmeticException e) { e.printStackTrace(); } finally { System.out.println("Blok finally w main."); } divideWithoutCatch(2, 1); divideWithoutCatch(2,0); } private static double divideWithCatch(int a, int b) { try { return a / b; } catch (ArithmeticException e) { e.printStackTrace(); throw e; } finally { System.out.println("Blok finally w metodzie divideWithCatch"); } } private static double divideWithoutCatch(int a, int b) { try { return a / b; } finally { System.out.println("Blok finally w metodzie divideWithoutCatch"); } } }
Mamy dwie metody – jednak z blokiem catch, drugi zaś tylko z blokami try oraz finally. Uruchamiając taki kod otrzymamy taki rezultat:
java.lang.ArithmeticException: / by zero at pl.rekrutacja.pytanie.Main.divideWithCatch(Main.java:20) at pl.rekrutacja.pytanie.Main.main(Main.java:7) java.lang.ArithmeticException: / by zero at pl.rekrutacja.pytanie.Main.divideWithCatch(Main.java:20) at pl.rekrutacja.pytanie.Main.main(Main.java:7) Exception in thread "main" java.lang.ArithmeticException: / by zero at pl.rekrutacja.pytanie.Main.divideWithoutCatch(Main.java:31) at pl.rekrutacja.pytanie.Main.main(Main.java:15) Blok finally w metodzie divideWithCatch Blok finally w main. Blok finally w metodzie divideWithoutCatch Blok finally w metodzie divideWithoutCatch
Na pierwszy rzut oka już widać, mając cztery bloki finally otrzymujemy dokładnie z nich cztery komunikaty. Wniosek jest oczywisty – blok finally wykonuje się zawsze. Bez względu na to czy użyliśmy return w bloku try, czy wcześniej rzuciliśmy wyjątek w bloku catch.
Po co blok finally
Zazwyczaj nie używa się bloku finally, ma jednak on swoje przeznaczenie. Często używa się go do “posprzątania” po sobie – mówiąc o sprzątaniu mam na myśli np. zamykanie strumienii, plików, połączeń itd.