0

When I run the following java code, I get the output as "ACDF". Could someone please explain how the runtime exception thrown in innermost catch block is handled? (I was expecting it to be handled in the block where "E" is being appended to result string variable)

public class HelloWorld {

    public static String someFunction() {
        String result = "";
        String str = null;

        try {
            try {
                try {
                    result += "A";
                    str.length();
                    result += "B";
                } catch (NullPointerException e) {
                    result += "C";
                    throw new RuntimeException(); // where this one goes????

                } finally {
                    result += "D";
                    throw new Exception();
                }
            } catch (RuntimeException e) {
                result += "E";
            }
        } catch (Exception e) {
            result += "F";
        }


        return result;
    }

    public static void main(String[] args) {
        System.out.println(someFunction());
    }
}

1 Answers1

-1

finally is always executed (ignoring special edge cases where the whole JVM dies). I am not kidding, even if you return, it will be executed before the return.

See Does a finally block always get executed in Java? for details.

So when you throw RuntimeException, you will first execute the finally that appends D.

Since you throw Exception there, you will run into the catch (Exception e) block now, as catch (RuntimeException e) does not match. Hence, you append F.

Thus, the result is ACDF.


Annotated code:

public class HelloWorld {

    public static String someFunction() {
        String result = "";
        String str = null;

        try {
            try {
                try {
                    result += "A";
                    str.length(); // throws NullPointerException
                    result += "B";
                } catch (NullPointerException e) { // continue here
                    result += "C";
                    throw new RuntimeException();

                } finally { // finally is always executed
                    result += "D";
                    throw new Exception(); // throwing this
                }
            } catch (RuntimeException e) { // does not match
                result += "E";
            }
        } catch (Exception e) { // matches, continue here
            result += "F";
        } // cool, all done


        return result; // returning ACDF
    }

    public static void main(String[] args) {
        System.out.println(someFunction());
    }
}
Zabuzard
  • 25,064
  • 8
  • 58
  • 82