Consider the following test case:
public class Main { static int a = 0; public static void main(String[] args) { try { test(); System.out.println("---"); test2(); } catch(Exception e) { System.out.println(a + ": outer catch"); a++; } } public static void test() { try { throw new Exception(); } catch (Exception e) { System.out.println(a + ": inner catch"); a++; } finally { System.out.println(a + ": finally"); a++; } } public static void test2() throws Exception { try { throw new Exception(); } finally { System.out.println(a + ": finally"); a++; } } } With output:
0: inner catch 1: finally --- 2: finally 3: outer catch What's the explanation for why in test() catch happens before finally while in test2() it's the other way around?
Yes, finally will be called after the execution of the try or catch code blocks.
So yes, finally is performed last, but only for the try block it's attached to.
In normal case when there is no exception in try block then the finally block is executed after try block. However if an exception occurs then the catch block is executed before finally block.
The finally block on a try / catch / finally will always run — even if you bail early with an exception or a return . This is what makes it so useful; it's the perfect place to put code that needs to run regardless of what happens, like cleanup code for error-prone IO.
The key points are these:
try-(catch)-finally block, the finally for that particular try block is performed lasttry blocks within another, and each of those nested try blocks can have their own finally, which would be performed last for those individual try blocksSo yes, finally is performed last, but only for the try block it's attached to.
So given the following snippet:
try { try { throw null; } finally { System.out.println("Finally (inner)"); } } catch (Throwable e) { System.out.println("Catch (outer)"); } This prints (as seen on ideone.com):
Finally (inner) Catch (outer) Observe that:
(inner), Finally is last (whether or not any catch was successful)Catch (outer) follows Finally (inner), but that's because Finally (inner) is nested inside another try block within (outer) Similarly, the following snippet:
try { try { throw null; } catch (Throwable e) { System.out.println("Catch (inner)"); } finally { System.out.println("Finally (inner)"); throw null; } } catch (Throwable e) { System.out.println("Catch (outer)"); } This prints (as seen on ideone.com):
Catch (inner) Finally (inner) Catch (outer) try-catch-finallyIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With