The only time a finally block will not be executed is when you call exit() before finally is reached. The exit() call will shutdown the JVM, so no subsequent line of code will be run.
EDIT: This is not entirely correct. See the comments below for additional information.
Answer from Gabriel Negut on Stack OverflowVideos
The only time a finally block will not be executed is when you call exit() before finally is reached. The exit() call will shutdown the JVM, so no subsequent line of code will be run.
EDIT: This is not entirely correct. See the comments below for additional information.
The finally block will always execute no matter if you return, or an exception is thrown within the try block.
See also section 14.19.2 Execution of try-catch-finally of the Java Language Specification
If the return in the try block is reached, it transfers control to the finally block, and the function eventually returns normally (not a throw).
If an exception occurs, but then the code reaches a return from the catch block, control is transferred to the finally block and the function eventually returns normally (not a throw).
In your example, you have a return in the finally, and so regardless of what happens, the function will return 34, because finally has the final (if you will) word.
Although not covered in your example, this would be true even if you didn't have the catch and if an exception were thrown in the try block and not caught. By doing a return from the finally block, you suppress the exception entirely. Consider:
public class FinallyReturn {
public static final void main(String[] args) {
System.out.println(foo(args));
}
private static int foo(String[] args) {
try {
int n = Integer.parseInt(args[0]);
return n;
}
finally {
return 42;
}
}
}
If you run that without supplying any arguments:
$ java FinallyReturn
...the code in foo throws an ArrayIndexOutOfBoundsException. But because the finally block does a return, that exception gets suppressed.
This is one reason why it's best to avoid using return in finally.
Here is some code that show how it works.
class Test
{
public static void main(String args[])
{
System.out.println(Test.test());
}
public static String test()
{
try {
System.out.println("try");
throw new Exception();
} catch(Exception e) {
System.out.println("catch");
return "return";
} finally {
System.out.println("finally");
return "return in finally";
}
}
}
The results is:
try
catch
finally
return in finally
These are two different things:
- The catch block is only executed if an exception is thrown in the try block.
- The finally block is executed always after the try(-catch) block, if an exception is thrown or not.
In your example you haven't shown the third possible construct:
try {
// try to execute this statements...
}
catch( SpecificException e ) {
// if a specific exception was thrown, handle it here
}
// ... more catches for specific exceptions can come here
catch( Exception e ) {
// if a more general exception was thrown, handle it here
}
finally {
// here you can clean things up afterwards
}
And, like @codeca says in his comment, there is no way to access the exception inside the finally block, because the finally block is executed even if there is no exception.
Of course you could declare a variable that holds the exception outside of your block and assign a value inside the catch block. Afterwards you can access this variable inside your finally block.
Throwable throwable = null;
try {
// do some stuff
}
catch( Throwable e ) {
throwable = e;
}
finally {
if( throwable != null ) {
// handle it
}
}
These are not variations, they're fundamentally different things. finally is executed always, catch only when an exception occurs.