0

Given the following try/catch block in java:

try{
  return;
}
catch(SomeException e){
  System.out.println(e);
}
finally{
  System.out.println("This is the finally block");
}

and according to this post: "Does finally always execute in Java?" I can see that the program's output will be 'This is the finally block'. However, I can't figure out how that would be possible since the print statement is preceded by a return...

I suspect that this behaviour has something to do with threading, however I am not certain. Please enlighten me. Thank you.

Community
  • 1
  • 1
stratis
  • 7,750
  • 13
  • 53
  • 94

3 Answers3

4

finally is executed before return statement. As java rule finally will always be executed except in case when JVM crashes or System.exit() is called.

Java Language Specification clearly mentions the execution of finally in different conditions:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
  • The docs state that "if there are any try statements within the method or constructor whose try blocks contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor". If I change my code in the try block to `return 0;` then my console will print 'This is the finally block' and then 0. However, if I place a print statement before `return 0;` then the order will be -the new try's block print statement, 'This is the finally block' and then 0. I am confused – stratis Nov 11 '13 at 05:22
0

return statement has no effect on the execution of finally block. The only way a finally block isn't executed is in case if JVM crashes/exits before executing finally block. Check this Link for more. So, if your code is replaced by

try{
  System.exit(0);
}
catch(SomeException e){
  System.out.println(e);
}
finally{
  System.out.println("This is the finally block");
}

The finally block won't execute

Prateek
  • 1,916
  • 1
  • 12
  • 22
0

Juned is correct. I also wanted to caution about throwing exceptions from finally blocks, they will mast other exceptions that happen. For example (somewhat silly example, but it makes the point):

boolean ok = false;
try {
   // code that might throw a SQLException
   ok = true;
   return;
}
catch (SQLException e) {
   log.error(e);
   throw e;
}
finally {
   if (!ok) {
      throw new RuntimeException("Not ok");
   }
}

In this case, even when an SQLException is caught and re-thrown, the finally throws a RuntimeException here and it it will "mask" or override the SQLException. The caller will receive the RuntimeException rather then the SQLException.

brettw
  • 10,664
  • 2
  • 42
  • 59