Yes. When a return leaves a try or catch, Java runs any applicable finally block before the method returns to its caller. If the block finishes normally, the pending return proceeds. If it returns or throws instead, that abrupt completion can replace the pending return.
What “before return” means
The return statement starts the method’s return, but control does not transfer to the caller until the applicable finally clauses have run. With nested try statements, those clauses run from the innermost outward.
As an Amazon Associate I earn from qualifying purchases.
The Java Language Specification defines this behavior; it is not an optional feature of javac. The relevant rules are in the Java SE 26 Language Specification sections on return statements and execution of try–finally statements.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →What happens to the pending return
If finally completes normally
The original return continues after the finally block finishes. For example, this method returns 7:
static int answer() {
try {
return 7;
} finally {
System.out.println("cleanup");
}
}
The message is printed before the caller receives the returned value.
If finally returns
A return inside finally replaces the pending return. In this example, the method returns 0, not 1:
Rank #2
static int answer() {
try {
return 1;
} finally {
return 0;
}
}
That behavior is legal, but it can hide the original return value or suppress an exception. Avoid returning from finally in ordinary application code.
If finally throws
An exception thrown by finally likewise interrupts the pending return. The caller observes the exception rather than the value that the try or catch was preparing to return, unless the exception is handled before it escapes.
When is the return value determined?
The return expression is evaluated as part of executing the return statement, before control enters the finally block. A normally completing finally does not retroactively recalculate that expression just because it changes a local variable afterward.
static int answer() {
int value = 7;
try {
return value;
} finally {
value = 9;
}
}
This method returns 7. The expression value has already supplied the value for the pending return when finally assigns 9. This is distinct from returning a mutable object reference: changing the referenced object in finally can affect the object the caller later observes, even though the reference expression was already evaluated.
Rank #4
What javac does
The Java SE 21 javac manual documents -Xlint:finally, which warns about finally clauses that cannot complete normally. Its example has a return 1 in a catch and a return 0 in finally; the method returns 0.
This is a warning, not a compile error, and it does not change Java’s runtime rules. The language specification determines the observable behavior; the compiler option helps identify a risky pattern.
Best Value
Why JVM implementation details are a separate issue
The Java Virtual Machine Specification, Java SE 26, discusses how a compiler can arrange finally code along paths that leave a try statement, including normal and abrupt transfers. That is an implementation explanation, not a guarantee that every compiler or class-file version uses one particular sequence of instructions. For Java source, the dependable rule is the language-level one: applicable finally code runs before control reaches the invoker, and its completion determines whether the pending return proceeds.
Quick Recap
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.




