Exceptions (unexpected events/errors) in Java interrupt the normal execution of a program. These exceptions may arise because of various reasons, such as invalid user input, attempting to access a null attribute, incompatible type casting, etc. To avoid such situations, Java offers an exception-handling mechanism.
Exception handling in Java is a process of managing runtime errors effectively. For this purpose, try, catch, and “finally” blocks are used. Try contains the code that may cause an exception, catch block catches, and handles that exception, while the “finally” block runs regardless of the exceptions.
How Does the Java Finally Block Work
The below figure illustrates how the “finally” block works in Java:
The above image shows that there are three cases in which the Finally block is executed:
- No exception arises.
- An Exception Occurs/Arises and is Handled.
- An Exception Occurs/Arises and is Not Handled.
Let’s discuss all these cases one by one with practical examples.
Case 1: No Exception Arises
When no exception occurs, the “finally” block executes right after the “try” block. In such a case, the “catch” block wouldn’t execute/run. Here is a practical example:
package exp;
public class exampleClass {
public static void main(String[] args) {
try {
String str = "javabeat.net";
System.out.println("Length of String: " +str.length());
}
catch (NullPointerException excep) {
System.out.println("NullPointerException Handled");
}
finally {
System.out.println("Welcome to JavaBeat.net");
}
}
}
Let’s understand this code block-by-block:
- We initialize a string in the try block and use the length() method to compute the total characters of the given string. In this case, the try block will execute and print the length of the given string.
- While working with strings we can face NullPointerException, so, in the catch block, we write the code to handle NullPointerException. The catch block wouldn’t execute in this case.
- In the “finally” block, we write a greeting message which will be printed on the console regardless of the exceptions.
Case 2: An Exception Occurs and is Handled
We initialize a string with a null value, so, in this case, an exception is raised which will be handled by the catch block:
package exp;
public class exampleClass {
public static void main(String[] args) {
try {
String str = null;
System.out.println("Length of String: " +str.length());
}
catch (NullPointerException excep) {
System.out.println("NullPointer Exception Handled");
}
finally {
System.out.println("Welcome to JavaBeat.net");
}
}
}
This program starts its execution from the try block where an exception occurs. So, the control moves to the catch block, which successfully handles the NullPointerException. At the end, the “finally” block executes which prints a greeting message:
Case 3: An Exception Occurs and is Not Handled
If an exception occurs and is not handled by the catch block, the “finally” block executes in that case as well:
package exp; public class exampleClass { public static void main(String[] args) { try { String str = null; System.out.println(“Length of String: ” +str.length()); } catch (NumberFormatException excep) { System.out.println(“NumberFormat Exception Handled”); } finally { System.out.println(“Welcome to JavaBeat.net”); } } } |
Here, in this code, first, the try block executes which throws an exception. The control moves to catch the block that is unable to handle the NullPointerException (in this case, it deals with the NumberFormatException only). Although the exception is not handled, still the “finally” block will execute:
How to Use Java Finally Block Without Catch Block
The “finally” block works perfectly fine even if we do not specify a catch block:
package exp;
public class exampleClass {
public static void main(String[] args) {
try {
String str = "Welcome to JavaBeat.net";
System.out.println("Length of String: " +str.length());
}
finally {
System.out.println("Welcome to JavaBeat.net");
}
}
}
Here, JVM first executes the try block and then finally block:
Does a Finally Block Execute When a Return Statement Occurs in a Try or Catch Block
Yes! If a try or catch block contains a return statement, JVM executes the “finally” block in that case as well:
package exp;
public class exampleClass {
public static String welcome() {
try {
String str = null;
System.out.println("Length of String: " + str.length());
return "Exit from try block";
} catch (NullPointerException excep) {
System.out.println("NullPointer Exception Handled");
return "Exit from Catch block";
} finally {
System.out.println("Welcome to JavaBeat.net");
}
}
public static void main(String[] args) {
welcome();
}
}
When we call the welcome() method from the main() method, first, JVM executes the try block and prints the length of the given string. After this, JVM encounters a return statement but executes the “finally” block before handing the control to the calling method.
In case an exception occurs/arises in the try block the control will be transferred to the catch block where the raised exception will be handled. For example, in the following code, the given string is “null”, so the control will be moved to the catch block:
package exp;
public class exampleClass {
public static String welcome() {
try {
String str = null;
System.out.println("Length of String: " + str.length());
return "Exit from try block"; }
catch (NullPointerException excep) {
System.out.println("NullPointer Exception Handled");
return "Exit from Catch block";
} finally {
System.out.println("Welcome to JavaBeat.net");
}
}
public static void main(String[] args) {
welcome();
}
}
The catch block handles the null pointer exception. After this, a return statement/keyword emerges in the catch block but before moving the control to the calling method, the “finally” block gets executed:
If a return statement appears in a “finally” block, then the return statements of try and catch will be ignored/skipped. So, it is highly recommended to avoid the use of the “return” statement in the “finally” block:
package exp;
public class exampleClass {
public static String welcome() {
try {
String str = null;
System.out.println("Length of String: " + str.length());
return "Exit from Try Block";
} catch (NullPointerException excep) {
System.out.println("NullPointer Exception Handled");
return "Exit from Catch Block";
} finally {
System.out.println("Welcome to JavaBeat.net");
return "Exit from Finally Block";
}
}
public static void main(String[] args) {
welcome();
}
}
This is how the return statement works with the try, catch, and finally blocks in Java.
Is There Any Case/Possibility When Java Finally Block Doesn’t Run?
Yes, there are some scenarios where the Finally block doesn’t execute. For example, an infinite loop, invoking the halt() method, invoking the System.exit() method, etc. Let’s consider some examples to understand it in a better way:
Case 1: Infinite Loop
If a loop executes infinite time, the finally block wouldn’t get a chance to run:
package exp;
public class exampleClass {
public static void welcome() {
try {
String str = "JavaBeat";
while (true) {
System.out.println("Length of String: " + str.length());
}
}catch (NullPointerException excep) {
System.out.println("NullPointer Exception Handled");
} finally {
System.out.println("Welcome to JavaBeat.net");
}
}
public static void main(String[] args) {
welcome();
}
}
In the try block, a while loop executes infinite times, so JVM wouldn’t be able to move the control to the “finally” block:
Case 2: Invoking System.exit()
In the following example, we use the “System.exit()” method in the try-and-catch blocks. If no exception arises, only the “try” block will run, else the catch block will execute and the program will be terminated when JVM encounters the “System.exit()” method. This means in both cases, the finally, block wouldn’t execute:
public class exampleClass {
public static void welcome() {
try {
String str = "JavaBeat.net";
System.out.println("Length of String: " + str.length());
System.exit(1);
} catch (NullPointerException excep) {
System.out.println("NullPointer Exception Handled");
System.exit(1);
} finally {
System.out.println("Welcome to JavaBeat.net");
}
}
public static void main(String[] args) {
welcome();
}
}
The input string was valid, so no exception occurred, therefore, the try block gets executed. The output shows that the “finally” block isn’t executed:
Case 3: Invoking halt()
When you invoke the halt() method in a Java program, JVM terminates the program execution immediately. Therefore, if you use the halt() method in a Try or Catch block, then the “finally” block won’t execute:
public class exampleClass {
public static void welcome() {
try {
String str = "JavaBeat.net";
System.out.println("Length of String: " + str.length());
Runtime.getRuntime().halt(1);
} catch (NullPointerException excep) {
System.out.println("NullPointer Exception Handled");
Runtime.getRuntime().halt(1);
} finally {
System.out.println("Welcome to JavaBeat.net");
}
}
public static void main(String[] args) {
welcome();
}
}
In this example, we use the halt() method in both try and catch blocks. Therefore, the “finally” block won’t execute no matter whether an exception occurs or not:
That’s all about the “finally” block in Java.
Conclusion
In Java, the “finally” block executes regardless of the exceptions. In the “finally” block, you can specify the code that you want to execute always, for example, the code for closing connections and files, freeing up threads, etc. Normally, the “finally” block always runs, however, there are some cases/scenarios where it may not execute. For example, an infinite loop, invoking the halt() method, invoking the System.exit() method, etc. This guide has demonstrated the use of the “finally” block through different examples.