Flow control in try-catch-finally in Java

An Exception is an unexpected event that might occur during the execution of a program. An unhandled exception can terminate a program abruptly. A try-catch block is meant to handle the exception without terminating the program abruptly. It can be done by wrapping the statement that might raise an exception in a try block followed by a catch block or a try block followed by a catch block and a finally block. The code that is wrapped in a try block is referred to as a protected code. This article explains the flow of control in try-catch-finally blocks with an example.

Try-catch-finally structure

try {
    //protected code
}
catch(Exception e) {
    // resolve issue
}
finally {
    // clean-up resources
}

A try block should always be followed by zero or more catch blocks or a finally block. The finally block is optional. A catch block should always be preceded by a try block. No code should be present between the try and the catch block. The catch block can have zero or more statements.

Flow control

try catch flow

When a statement raises an exception in the try block, the rest of the statements are ignored. The exception will be caught in the matching catch block. If the exception cannot be handled in one of the catch blocks following the try block, it is handled by the JVM’s default exception handler. If a finally block is present after the catch block or the try block, it will always be executed regardless of the exception. Since a finally block will always be executed, it can be used to close resources opened in the try block. However, the finally block can even be skipped when one of the following occurred.

  1. System.exit() is called.
  2. An exception arises in the finally block itself.
  3. The thread of execution died before the finally block.

So it must be ensured that none of these cases occurs during the execution.

An Example

Consider the following program.

class tryCatch {
    public static void main(String[] args) {
        int n = 100;
        int i = 0;
        try {
            System.out.println("Control: executing statements in try block");
            System.out.println(n/i);
        }
        catch (NullPointerException e) {
            System.out.println("Control: executing statements in 1st catch block");
            System.out.println("Exception: "+e.getMessage());
        }
        catch (ArithmeticException e) {
            System.out.println("Exception: "+e.getMessage());
            System.out.println("Control: executing statemenrs in 2nd catch block");
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Exception: "+e.getMessage());
            System.out.println("Control: executing statemenrs in 3rd catch block");
        }
        finally {
            System.out.println("Control: executing statements in finally block");
        }
        System.out.println("Control: about to exit");
    }    
}
  1. This program will raise an ArithmeticException upon executing the statement in line number 7.
  2. While looking for a matching catch block, the first one is skipped as the types vary. The 2nd catch block will be executed as their types match. The statements in the 2nd catch block will be executed and all the other catch blocks are skipped.
  3. If the finally block is present, the statements in it will be executed. Otherwise, the rest of the code will be executed.

The program produces the following output as expected.

Control: executing statements in try block
Exception: / by zero
Control: executing statemenrs in 2nd catch block
Control: executing statements in finally block
Control: about to exit

Leave a Reply

Your email address will not be published. Required fields are marked *