Sunday, 29 July 2012

Is Finally Always Called in a Try Catch Java Statement?

The short answer is no if System.exit() is called within a try statement (see here for more details).

Otherwise, as mentioned in the Javadoc, the finally statement is always executed even if return, continue, or break are called within try or catch. We can check this with the following code example:
public class TryCatchFinally {

    public static void main(String[] args) {
        print("Before Check");
        check();
        print("After Check");
    }

    public static void check() {
        for (int i=0;i<3;i++) {
            String round = "Round " + (i+1) + " ";
            print(round + "before try");
            try {
                if ( (i%3) == 0 ) {
                    print(round + "before break");
                    break;
                } else if ( (i%3) == 1 ) {
                    print(round + "before continue");
                    continue;
                } else { // (i%3) == 2
                    print(round + "before return");
                    return;
                }
            } catch(Throwable t) {
                print(round + "Caught throwable:\n" + t);
            } finally {
                print(round + "in finally");
            }
            print(round + "after try statement");
        }
        print("After for statement");
    }

    public static void print(String s) {
        System.out.println(s);
    }

}

Testing break in try statement

If we run the above program as is, we get:

Before Check
Round 1 before try
Round 1 before break
Round 1 in finally
After for statement
After Check

We can conclude the following:
  • Even though break is performed, the finally statement is called.
  • Statements after try and the for loop are not executed.
  • The check() method returns properly.

Testing continue in try statement

If we comment the break and return statement (and corresponding print), and run the program again, we get:

Before Check
Round 1 before try
Round 1 in finally
Round 1 after try statement
Round 2 before try
Round 2 before continue
Round 2 in finally
Round 3 before try
Round 3 in finally
Round 3 after try statement
After for statement
After Check

We can conclude the following:
  • Even though continue is performed, the finally statement is called.
  • The statement after try is not executed for continue.
  • The for loop post statement is executed.
  • The check() method returns properly.

Testing return in try statement

If we comment the break and continue statement (and corresponding print), and run the program again, we get:

Before Check
Round 1 before try
Round 1 in finally
Round 1 after try statement
Round 2 before try
Round 2 in finally
Round 2 after try statement
Round 3 before try
Round 3 before return
Round 3 in finally
After Check

We can conclude the following:
  • Even though return is invoked, the finally statement is called.
  • Statements after try and the for loop are not executed.
  • The check() method returns properly.

Conclusion

  • If return, continue, or break are invoked in try, it does not prevent finally from being executed.
  • In all cases, if the try statement belongs to a called method, this method returns properly.