
img src: bing image
First, something to think about... :
- When does
finallyin Java codes be executed? - Do codes after
finallyget executed at all? - Does
finallyintry-catch-finallyblock 100% gets executed? - If there is
returnmixed up withfinally, what is the order of execution?
Second, a few things to keep in mind... :
-
There is good chance exceptions will occur in
tryblock. One or more exceptions will be throw out. So, there can be multiplecatchaftertryblock. -
If exceptions are isolated, then
catchs can be arranged in whatever order you deem fit. But should there be inheritance hierarchy between those exceptions, you will need to put children exceptions before parent exceptions. This aims to let child exception gets caught by childcatchinstead of parents'catch. So that specific exception's info can be output rather than a general parents' exception prompt. -
Generally, if exception did not occur in
tryblock, thencatchdo not get to be excuted. But regardless of exceptions intryblock, should there be afinally, thenfinallygets executed.
Note: This is under general circumstance. I will come back to this later, and talk about other scenarios. -
Codes after
finallyget executed or not depend on whether there isretuenintryorcatch.
In this blog, I will focus on these topics:
- When do codes after
finallyin Java execute? - When does
finallyin Java codes be executed? Or doesn't be executed? finallyis executed before or afterreturn?- If there is also
returninfinally, then should it just return? Willretuenintryreturn? - If there is no
returninfinallybut intry, then how willretuenintryreturn? In what order? - If
finallydo not havereturnin it but altered the variable to return. Then how willretuenintryreturn? Altered or unaltered?

img src: bing image
Now, let's dive right in... :
1. When do codes after finally in Java execute?
See codes below:
public class TestFinally {
public static void main(String[] args){
try{
return;
}
finally{
System.out.println("Finally");
}
}
}
Program Output:
Finally
conclusion1: No exception occured,
finallystill gets executed.
If we replace return to a normal output code:
public class TestFinally {
public static void main(String[] args){
try{
int a=3;
a+=5;
System.out.println(a);
}
finally{
System.out.println("Finally");
}
int b=5;
b+=5;
System.out.println(b);
}
}
Program Output:
8
Finally
10
conclusion2: Codes after
finallywill be executed.
Adding return in try won't be compiled because compiler found out this part of codes:
int b=5;
b+=5;
System.out.println(b);
are unreachable code.
Some extra examples, example set 1:
public class TestFinally {
public static void a() throws Exception{
try{
throw new Exception();
}
catch(Exception e){
System.out.println("exception000");
}
finally{
System.out.println("finally111");
}
}
public static void main(String[] args){
try{
a();
}
catch(Exception e){
System.out.println("exception");
}
System.out.println("finished");
}
}
Program Output:
exception000
finally111
finished
Exception was caught in a(), catch in main will not be executed. Codes after catch will be executed.
If we commented catch in a():
public class TestFinally {
public static void a() throws Exception{
try{
throw new Exception();
}
/*catch(Exception e){
System.out.println("exception000");
}*/
finally{
System.out.println("finally111");
}
}
public static void main(String[] args){
try{
a();
}
catch(Exception e){
System.out.println("exception");
}
System.out.println("finished");
}
}
Program Output:
finally111
exception
finished
Exception did not get caught in a(), but was caught at catch in main. Codes after catch will be executed.
If we commented finally in a() instead:

img src: bing image
package trycatchfinally;
public class TestFinally {
public static void a() throws Exception{
try{
throw new Exception();
}
catch(Exception e){
System.out.println("exception000");
}
/*finally{
System.out.println("finally111");
}*/
}
public static void main(String[] args){
try{
a();
}
catch(Exception e){
System.out.println("exception");
}
System.out.println("finished");
}
}
Program Output:
exception000
finished
Exception was caught in a(), codes after catch in main will be executed.
example set 2:
public class TestFinally {
public static String output="";
public static void a(int i){
try{
if(i==1){
throw new Exception();
}
output+="1";
}
catch(Exception e){
output+="2";
return;
}
finally{output+="3";}
output+="4";
}
public static void main(String[] args){
a(0);
a(1);
System.out.println(TestFinally.output);
}
}
Program Output:
13423
If we remove return phrase... :
package trycatchfinally;
public class TestFinally {
public static String output="";
public static void a(int i){
try{
if(i==1){
throw new Exception();
}
output+="1";
}
catch(Exception e){
output+="2";
//return;
}
finally{output+="3";}
output+="4";
}
public static void main(String[] args){
a(0);
a(1);
System.out.println(TestFinally.output);
}
}
Program Output:
1234234
conclusion3: If there is
returnintry, codes afterfinallywill not be executed. Same thing goes forcatch.
2. When does finally in Java codes be executed? Or doesn't be executed?
- Case 1: Never reached
tryblock, just skipped. Thenfinallywill not be executed. Which also indicates the necessary but not sufficient condition forfinallybe executed istryblock must be reachable, not skipped. - Case 2: There is something like
System.exit(0);intryblock,System.exit(0);shuts down JVM, which meansfinallywill 100% not be executed. - Case 3: JVM crashed first or get killed first.
- Case 4: there is an infinite loop (or some other non-interruptable, non-terminating statement) in the
tryblock.
Now that we know codes after finally get executed or not depend on whether there is retuen in try or catch, it's time to think deeper...
3. finally is executed before or after return ?
One statement I agree on:
finallyin Java codes is executed afterreturn, but beforereturnreturns value.
See codes below:
public class TestFinally {
public static void main(String[] args) {
System.out.println(test1());
}
public static int test1() {
int b = 20;
try {
System.out.println("try");
return b += 80;
}
catch (Exception e) {
System.out.println("catch");
}
finally {
System.out.println("finally");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
}
return b;
}
}
Program Output:
try
finally
b>25, b = 100
100
returnis executed first, but beforereturnreturns value,finallyis executed. Thenreturnreturns value.
public class TestFinally {
public static void main(String[] args) {
System.out.println(test11());
}
public static String test11() {
try {
System.out.println("try");
return test12();
} finally {
System.out.println("finally");
}
}
public static String test12() {
System.out.println("return statement");
return "after return";
}
}
Program Output:
try
return statement
finally
after return
4. If there is also return in finally, then should it just return? Will retuen in try return?
See codes below:
public class TestFinally {
public static void main(String[] args) {
System.out.println(test2());
}
public static int test2() {
int b = 20;
try {
System.out.println("try");
return b += 80;
} catch (Exception e) {
System.out.println("catch");
} finally {
System.out.println("finally");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
return 200;
}
// return b;
}
}
Program Output:
try
finally
b>25, b = 100
200
conclusion:
returninfinallywill return, regardless ofreturnintry. Meaning it will overridereturnintry.
Also, once there isreturninfinally,return b;outside becomes unreachable. It will need to be commented out.is executed. Thenreturnreturns value.
5. If there is no return in finally but in try, then how will retuen in try return?
try{
return {expression A};
}finally{
do some work;
}
We now know that
finallyblock generally gets executed. But in what order?
- execute {expression A}, push result into top of operand stack. (Some say copy to top of operand stack.)
- copy the top of operand stack (result of {expression A}) to local variable table.
- execute
finally.- push value in local variable table in step 2 back to operand stack. (Some say copy it to top of operand stack, not exactly push.)
- return value at the top of operand stack.
conclusion: After step 1, value to return is already set. In order to execute finally,
JVM will temporarily move the return value to local variable table, to free up operand stack for finally.
And when finally is complete, JVM will return the value to top of operand stack.
So no matter what finally do (except returning a static value like return 200;),
value to return will not be affected.
finally is designed for clean up, not alter return value.
6. If finally do not have return in it but altered the variable to return.
Then how will retuen in try return? Altered or unaltered?
See codes below:
public class TestFinally {
public static void main(String[] args) {
System.out.println(test3());
}
public static int test3() {
int b = 20;
try {
System.out.println("try");
return b += 80;
} catch (Exception e) {
System.out.println("catch");
} finally {
System.out.println("finally");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b = 150;
}
return 2000;
}
}
Program Output:
try
finally
b>25, b = 100
100
conclusion: return did not changed to 150, so if finally try to alter a basic data types variables like an int or double, affects would not take place.
But if it tries to alter a wrapper class like Interger, or some normal object like Map map = new HashMap(); , affects would take place.
reference:
[1] https://stackoverflow.com/questions/65035/does-finally-always-execute-in-java