iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Yes. In Java, an applicable finally block runs before a return from its associated try or catch transfers control to the caller. If the block finishes normally, the pending return proceeds. If it returns or throws, that abrupt completion can replace the pending return.
What “before return” means in Java
A return statement starts the method’s return, but the method does not transfer control to its invoker until applicable finally clauses have run. The Java Language Specification, Java SE 26 Edition defines this source-level behavior. If try/finally blocks are nested, the innermost applicable finally runs first.
What the caller ultimately observes depends on how the finally block completes:
| How finally completes | What reaches the caller |
|---|---|
| Normally, without returning or throwing | The pending return proceeds. |
| Abruptly, by returning | The return from finally replaces the pending return. |
| Abruptly, by throwing an exception | The exception replaces the pending return, unless it is handled elsewhere. |
Why a return in finally changes the result
Consider this method:
static int result() {
try {
return 1;
} finally {
return 0;
}
}
The method returns 0. The return from the finally block completes abruptly and supersedes the pending return of 1. This is legal Java, but it is usually a poor pattern: it can hide an earlier return value or suppress an exception that was already in flight.
The same principle applies if finally throws instead of returning. For example, a return in try does not guarantee that the caller receives its value if the finally block throws an exception before control gets there.
When a value is evaluated and when finally runs
The return expression is evaluated as part of executing the return statement; the applicable finally clause then runs before the return completes. Keep that distinction in mind when a finally block reassigns a local variable:
Rank #2
static int result() {
int value = 1;
try {
return value;
} finally {
value = 0;
}
}
This method returns 1. The return value has already been produced from value before the reassignment in finally; changing the local afterward does not change that already-produced value. That differs from returning directly inside finally, which creates a new return that can replace the pending one.
Recommended Free Tools
What javac does—and what its warning means
The Java SE 21 javac command manual documents -Xlint:finally, which warns about finally clauses that cannot complete normally. Its example uses a return in catch and another in finally; the method returns the value from finally.
The warning is a diagnostic, not a compile-time prohibition or a change to the language’s runtime behavior. The Java Language Specification defines what Java code means; the javac manual describes a warning that can help identify a risky pattern. The warning does not mean every use of finally is problematic.
How the JVM specification fits in
The Java Virtual Machine Specification, Java SE 26, Chapter 3 discusses how finally can be compiled, including arranging for its code to run on paths that leave a try statement through normal or abrupt transfer. That is an implementation explanation, not a guarantee that every compiler or class-file version uses one particular instruction sequence. For Java source code, the observable guarantee comes from the language specification.
Quick Recap
Best Value
Rank #4
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

