The finally block in Java is a crucial block that is used to execute essential code, like closing connections and handling exceptions.
The Java finally block is guaranteed to run, regardless of whether an exception is caught or not. This block should include any essential statements that must be executed regardless of whether an exception is encountered.
The finally block follows the try-catch block.
Flowchart of the finally block
Note: If we do not handle the exception before terminating the program, the JVM executes the finally block (if any).
Why use a Java finally block?
- finally block in Java can be used to put " cleanup " code, such as closing a file, closing a connection, etc.
- The important statements to be printed can be placed in the finally block.
Usage of the finally Block
Let's explore various scenarios in which the Java finally block can be utilized.
Case 1: When an exception does not occur
Consider the following example demonstrating the scenario where a Java program runs without throwing any exceptions, and the finally block is executed following the try block.
Example
class Main
{
public static void main(String args[])
{
try {
//The below code does not throw any exception
int data=25/5;
System.out.println(data);
}
//catch won't be executed
catch(NullPointerException e) {
System.out.println(e);
}
//executed regardless of exception occurred or not
finally {
System.out.println("Finally block is always executed");
}
System.out.println("rest of the code...");
}
}
Output:
5
Finally block is always executed
rest of the code...
Case 2: When an exception occurs but is not handled by the catch block
The Java code below encounters an exception that cannot be managed by the catch block. Nevertheless, the finally block runs following the try block, leading to an abnormal termination of the program.
Example
public class Main
{
public static void main(String args[])
{
try {
System.out.println("Inside the try block");
//The below code throws a divide by zero exception
int data=25/0;
System.out.println(data);
}
//cannot handle Arithmetic type exception can only accept a Null Pointer type exception
catch(NullPointerException e){
System.out.println(e);
}
//executes regardless of exception occurred or not
finally {
System.out.println("Finally block is always executed");
}
System.out.println("rest of the code...");
}
}
Output:
Inside the try block
Finally block is always executed
Runtime Error:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:8)
Case 3: When an exception occurs and is handled by the catch block
Consider the following scenario demonstrating the occurrence of an exception in Java code, which is then managed by the catch block. Subsequently, the final block is triggered following the execution of the try-catch block. The remaining code proceeds with its normal execution flow.
Example
public class Main
{
public static void main(String args[])
{
try {
System.out.println("Inside the try block");
//The below code throws a divide by zero exception
int data=25/0;
System.out.println(data);
}
//handles the Arithmetic Exception / Divide by zero exception
catch(ArithmeticException e){
System.out.println("Exception handled");
System.out.println(e);
}
//executes regardless of exception occurred or not
finally {
System.out.println("Finally block is always executed");
}
System.out.println("rest of the code...");
}
}
Output:
Inside the try block
Exception handled
java.lang.ArithmeticException: / by zero
Finally block is always executed
rest of the code...
Guideline: Every try block may contain no catch blocks or multiple catch blocks, while the finally block must be singular.
Note: The finally block will not execute if the program exits (either by calling System.exit or by causing a fatal error that causes the process to abort).
Best Practice
- Resource Management: To prevent resource leaks, use the finally block to close resources such as files, database connections, or network sockets.
- Avoid Return Statements: Avoid using return statements in the final block, as this can obfuscate the program's flow and make it more difficult to comprehend.
- Nested try-finally: To guarantee that every resource is appropriately closed when working with several resources, take into account utilizing nested Try-Finally blocks.
Utilize try-with-resources: The try-with-resources feature, introduced in Java 7, automatically closes resources and is considered the recommended approach for resource management.
try (FileInputStream inputStream = new FileInputStream("File.txt")) {
// Performing the file operations
} catch (IOException e) {
System.out.println("Exception: " + e);
}
- Consistent Cleanup: Make sure that the code used for cleanup is consistent and does not raise any exceptions that could confuse the initial issue. If required, utilize nested try-catch inside finally.
- Execution Circumstances: Be aware that the final block always runs, with the exception of situations in which the JVM ends the try or catch blocks via calls such as System.exit or in which there are infinite loops or daemon threads.
- Could you explain the significance of the finally block in programming?
Java finally Block FAQs
The finally clause is utilized to run cleanup tasks, like closing file streams or releasing resources. It guarantees the execution of this code block even in the event of an exception being thrown.
- Is the execution of the finally block guaranteed?
Certainly, the finally block will be executed irrespective of whether an exception is thrown, except in cases where the JVM terminates due to a call to System.exit or a critical error.
- Is it possible for a return statement to be included within a finally block?
Indeed, employing a return statement within the finally block has the capability to supersede any return statements within the try or catch blocks. This could potentially result in unforeseen outcomes.
- Is it obligatory to incorporate a finally block?
While it is not mandatory to use the finally block for resource cleanup, it is considered good practice. Although you can handle exceptions using try-catch without the finally block, the finally block guarantees that the cleanup code will be executed.
In the scenario where an exception occurs within the finally block, the exception will override any previous exceptions, and the latest exception will be propagated.
In situations where an exception arises within the finally block, it has the capability to mask exceptions thrown in the try or catch blocks, thereby potentially hiding the initial exception.