During the application development process, different kinds of exceptions can occur. These exceptions are closely related to errors caused due to invalid operators, heap overload, out-of-memory, and so on. These exceptions halt the working of an overall program or generate undesired results until they get resolved. To execute specific lines of code without depending on the exception the “finally” block is used. This block is not affected by the rise of any exceptions caused in a code and gets executed in all scenarios.

This guide explains the working of a “finally” block in Java by covering the following sections:

  • How to Use a “finally” Block for Catching Exceptions?
  • Execution Flow of the “finally” Block With the “try” and “catch” Blocks
  • Scenarios When “finally” Block is Not Executed

How to Use the “finally” Block for Catching Exceptions?

The “finally” block does not perform catching exceptions primarily. It only ensures the execution of a certain code block whether an exception occurs or not. This block mostly contains the cleanup tasks to release the consumed resources. Using the “finally” block the user can perform additional actions or logging when an exception is caught by the “try/catch” block. In addition, the “finally” block is only accessible with the “try”, “catch” or both “try/catch” blocks.

Control Flow of try-catch-finally Block

As already discussed, the process of catching exceptions consists of three blocks “try”, “catch”, and “finally”. The “try” block contains lines of code that may or may not generate an exception. If the exception rises then the control moves toward the “catch” block where that raised exception is handled. If there is no catch block for the raised exception then the process gets halted. However, the code in a “finally” block gets executed as its execution does not depend on the raised exception. 

The visual representation is shown below:

Syntax

The syntax of a “finally” block with the “try/catch” block is mentioned below:

try {
//Code that may raise Exceptions
}
catch (Exception e) {
// Handle Raised Exceptions
}
finally {
//Execute this Block in all scenarios }

Let’s consider a basic example that uses the try-catch-finally block.

Execution Flow of the “finally” Block With the “try” and “catch” Blocks

Let’s proceed and practically implement a couple of use-case scenarios where the “finally” block gets executed.

Scenario 1: Exception is Not Thrown By Try Block

In this example, the code in a “try” block executes seamlessly without generating any exception or error. This skips the catch block and directly executes the “finally” block:

import java.util.*;
public class FinallyBlock {
public static void main(String[] args) {
  try {
  List<Double> demoList = new ArrayList<>();
  demoList.add(1.09);
  demoList.add(23.73);
  demoList.add(93.5);
  System.out.println("Try Block -> Retrieving Index Number 1 Element: " + demoList.get(1));
  } catch (Exception excep) {
  System.out.println("Catch Block -> Raised Exception: " + excep.getMessage());
  } finally {
  System.out.println(" Finally Block -> Element Retrieval");
  }
}
}

The description of the above code block:

  • First, inside the try block create a List named “demoList” and print its element residing at index number “1”. Utilize the “get()” method to retrieve this List element according to index number.
  • Then, the “catch” block catches and displays any raised exception from the “try” block.
  • In the end, utilize the “finally” block to display a random end message on the console.

The output shows the execution of a “try” and “finally” block only because no exception is raised:

Scenario 2: Exception is Thrown and Handled

In this case, the exception is raised by the “try” block and handled successfully via the “catch” block. After handling of exception, the code in a “finally” block gets executed:

import java.util.*;
public class FinallyBlock {
public static void main(String[] args) {
  try {
  List<Double> demoList = new ArrayList<>();
  demoList.add(1.09);
  demoList.add(23.73);
  demoList.add(93.5);
  System.out.println("Try Block -> Retrieving Index Number 6 Element: ");
  System.out.println("\t" + demoList.get(6));
  }
  catch (Exception excep) {
  System.out.println("\n  Catch Block -> Raised Exception: " + excep.getMessage());
  }
  finally {
  System.out.println("\n\tFinally Block -> Element Retrieval");
  }
}
}

Explanation of the above code is written below:

  • Create a List having “3” elements and use the “get()” method to retrieve the element residing at index number “6”. This raises an “IndexOutOfBoundsException” because the List with “3” elements has the maximum index number of “2”.
  • Next, utilize the “catch” block that catches any raised exception and displays both custom and exception messages.
  • In the end, utilize the “finally” block to display an ending or random message on the console.

The output confirms the execution of a “finally” block after the execution gets handled:

Scenario 3: Exception is Thrown But Not Handled

In this example, the “IndexOutOfBoundsException” is thrown by the “try” block to access the out-of-bound List element. On the other hand, the “catch” block fails to catch this exception because it asks to catch only the “NullPointerException”. This leads to the occurrence of exceptions and blocking of the program. However, the code in the “finally” block still gets executed:

import java.util.*;
public class FinallyBlock {
public static void main(String[] args) {
  try {
  List<Double> demoList = new ArrayList<>();
  demoList.add(1.09);
  demoList.add(23.73);
  demoList.add(93.5);
  System.out.println("Try Block -> Retrieving Index Number 6 Element: ");
  System.out.println("\t" + demoList.get(6));
  }
  catch (NullPointerException excep) {
  System.out.println("\n Catch Block -> Raised Exception: " + excep.getMessage());
  }
  finally {
  System.out.println("\n   Finally Block -> Unhandled Exception");
  }
}
}

The above code is similar to the one explained in the above sections. Only the “catch” block is modified to catch and handle only “NullPointerException” related exceptions. 

The output confirms the occurrence of an exception and the execution of the “finally” code block:

Scenario 4: Method Returns From “try” Block

The “finally” block executes its lines of code even if the “try” block contains a return statement, as demonstrated in below code example:

import java.util.*;
public class FinallyBlock {
public static double show(List<Double> demoList) {
  double result4 = -1.0;
  try {
  System.out.println("Try Block -> Retrieving Index Number 6 Element: ");
  result4 = demoList.get(1);
  return result4;
  }
  catch (NullPointerException excep) {
  System.out.println("\n  Catch Block -> Raised Exception: " + excep.getMessage());
  return -1;
  }
  finally {
  System.out.println("\n   Finally Block -> Unhandled Exception");
  }
}
public static void main(String[] args) {
  List<Double> demoList = new ArrayList<>();
  demoList.add(1.09);
  demoList.add(23.73);
  demoList.add(93.5);
  System.out.println("\n\tMain() Method -> " + show(demoList));
}
}

The description of the above code block:

  • First, create a method “show()” accepting a List named “demoList” as an argument. It contains a “try” block that selects and returns the specific element of a List using the “get()” method. Store the retrieved element in a new variable and return it using the “return” keyword.
  • Next, use the “catch” and “finally” blocks to catch any raised exception and perform additional actions respectively.
  • In the “main()” method, define a List named “demoList” and pass this List as an argument in the “show()” method.

Output:

Scenario 5: Method Returns From “catch” Block

The utilization of a “return” statement from the “catch” block does not affect the execution process of a “finally” block:

import java.util.*;
public class FinallyBlock {
public static double working(List<Double> demoList) {
  double result4 = -1.0;
  try {
  System.out.println("Try Block -> Retrieving Index Number 6 Element: ");
  result4 = demoList.get(6);
  return result4;
  }
  catch (Exception excep) {
  System.out.println("\n  Catch Block -> Raised Exception: " + excep.getMessage());
  return -0.0;
  }
  finally {
  System.out.println("\n   Finally Block -> Value Returned From Catch Block");
  }
}
public static void main(String[] args) {
  List<Double> demoList = new ArrayList<>();
  demoList.add(1.09);
  demoList.add(23.73);
  demoList.add(93.5);
  System.out.println("\n\tMain() Method -> " + working(demoList));
}
}

The above code is the same as the one described in the above section:

  • First, modify the “try” block to retrieve and return the List element residing at index number “6”. This retrieval raises the exception because the maximum index number of our List is “2”. 
  • This exception activates the “catch” block and makes it handle the exception and return a random value.
  • After that, the code in a “finally” block gets executed according to the flow. This returned value is then displayed from the “main()” method. 

Output:

Scenarios When “finally” Block is Not Executed

There are some techniques or approaches by which the execution of the “finally” block gets terminated. These approaches terminate or block the execution of the remaining code as well. So the user must use these approaches with caution and after a proper understanding of their effect on the current Java program. These approaches are listed below:

  • Use of “halt()” Method
  • Use of “System.exit()” Method
  • Daemon Thread
  • Utilization of Infinite Loop

Let’s implement some of the mentioned approaches to block execution for the “finally” block in Java.

Blocks the Execution of “finally” Block Using “halt()” Method

Insert the value of “0” inside the “halt()” method to block or halt the execution of an entire program. To perform the halting at runtime invoke this method using the “getRuntime()” method (of the “Runtime” class). In the below code, the halting is performed from the “try” block to prevent the execution of a “finally” block:

import java.util.*;
public class FinallyBlock {
public static void halting(List<Double> demoList) {
double result4 = -1.0;
try {
  System.out.println("Try Block -> Retrieving Index Number 6 Element: ");
  result4 = demoList.get(2);
  Runtime.getRuntime().halt(0);
}
catch (Exception excep) {
  System.out.println("\n Catch Block -> Raised Exception: " + excep.getMessage());
}
finally {
  System.out.println("\n Finally Block -> Value Returned From Catch Block");
}
}
public static void main(String[] args) {
  List<Double> demoList = new ArrayList<>();
  demoList.add(1.09);
  demoList.add(23.73);
  demoList.add(93.5);

  halting(demoList);
}
}

The above code is similar to the one explained in previous sections. Only insert the “Runtime.getRuntime().halt(0)” method inside the “try” block. This blocks JVM from executing any code written after the “try” block and hence prevents the execution of a “finally” block.

Output:

Blocks the Execution of “finally” Block Using “System.exit(0)” Method

The “System.exit()” exits the currently running program by terminating the JVM. The lines of code written next to this line remain unexecuted and generate results for the code that has already been executed. As shown below:

import java.util.*;
public class FinallyBlock {
public static void halting(List<Double> demoList) {
double result4 = -1.0;
try {
  System.out.println("Try Block -> Retrieving Index Number 6 Element: ");
  result4 = demoList.get(7);
}
catch (Exception except) {
  System.out.println("\n Catch Block -> Raised Exception: " + except.getMessage());
  System.exit(1);
}
finally {
  System.out.println("\n Finally Block -> Value Returned From Catch Block");
}
}
public static void main(String[] args) {
  List<Double> demoList = new ArrayList<>();
  demoList.add(1.09);
  demoList.add(23.73);
  demoList.add(93.5);

  halting(demoList);
}
}

In the above code block:

  • The exception is thrown from the “try” block which is caught by the “catch” block. This catch block prints an exception and a custom message on the console.
  • Moreover, invoke the “System.exit()” method and pass the random integer of “1” as an exit status code to terminate the execution of a program.

The remaining code is similar to the one described in the above sections.

The output confirms the execution of the program before the “finally” block:

That’s all about the usage and working of a “finally” block.

Conclusion

In Java, use the “finally” block along the “try/catch” block to perform additional actions or operations without depending on exceptions. Code written in the “finally” block gets executed whether the “exception” is raised or the raised exception is handled or unhandled. The “finally” block executes even when there is a “return” statement in the “try” or “catch” block. To block the execution of a “finally” block, use the “halt()”, “System.exit()” Methods, or utilize an Infinite Loop. This guide has explained the working of a “finally” block in Java.