According to the Java Language Specification, Section §14.20.2
A try statement with a finally block is executed by first executing the try block. Then there is a choice:
- If execution of the try block completes normally, then the finally block is executed, and then there is a choice:
- If the finally block completes normally, then the try statement completes normally.
- If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S.
...
- If execution of the try block completes abruptly for any other reason
R, then the finally block is executed, and then there is a choice:
- If the finally block completes normally, then the try statement completes abruptly for reason R.
- If the finally block completes abruptly for reason S, then the try statement completes bruptly for reason S (and reason R is discarded).
When there is no return
in the try
block, then the finally
block is executed and the return
in the finally
block will be used.
When there is a return
in the try
block, then it can be conscidered that the try
block finished abruptly, however, according to the JLS, the finally
block will still be executed before the code returns.
You can also refer to Section §14.17 of the JLS to help understand the return statement.
Of interest, the note at the bottom of the section:
The preceding descriptions say "attempts to transfer control" rather
than just "transfers control" because if there are any try statements
(§14.20) within the method or constructor whose try blocks or catch
clauses 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. Abrupt completion of a finally clause can disrupt the
transfer of control initiated by a return statement.