Try-finally block prevents StackOverflowError Try-finally block prevents StackOverflowError java java

Try-finally block prevents StackOverflowError


It doesn't run forever. Each stack overflow causes the code to move to the finally block. The problem is that it will take a really, really long time. The order of time is O(2^N) where N is the maximum stack depth.

Imagine the maximum depth is 5

foo() calls    foo() calls       foo() calls           foo() calls              foo() which fails to call foo()           finally calls              foo() which fails to call foo()       finally           foo() calls              foo() which fails to call foo()           finally calls              foo() which fails to call foo()    finally calls       foo() calls           foo() calls              foo() which fails to call foo()           finally calls              foo() which fails to call foo()       finally           foo() calls              foo() which fails to call foo()           finally calls              foo() which fails to call foo()finally calls    foo() calls       foo() calls           foo() calls              foo() which fails to call foo()           finally calls              foo() which fails to call foo()       finally           foo() calls              foo() which fails to call foo()           finally calls              foo() which fails to call foo()    finally calls       foo() calls           foo() calls              foo() which fails to call foo()           finally calls              foo() which fails to call foo()       finally           foo() calls              foo() which fails to call foo()           finally calls              foo() which fails to call foo()

To work each level into the finally block take twice as long an the stack depth could be10,000 or more. If you can make 10,000,000 calls per second, this will take 10^3003 seconds or longer than the age of the universe.


When you get an exception from the invocation of foo() inside the try, you call foo() from finally and start recursing again. When that causes another exception, you'll call foo() from another inner finally(), and so on almost ad infinitum.


Try running the following code:

    try {        throw new Exception("TEST!");    } finally {        System.out.println("Finally");    }

You will find that the finally block executes before throwing an Exception up to the level above it. (Output:

Finally

Exception in thread "main" java.lang.Exception: TEST! at test.main(test.java:6)

This makes sense, as finally is called right before exiting the method. This means, however, that once you get that first StackOverflowError, it will try to throw it, but the finally must execute first, so it runs foo() again, which gets another stack overflow, and as such runs finally again. This keeps happening forever, so the exception is never actually printed.

In your bar method however, as soon as the exception occurs, it is just thrown straight up to the level above, and will be printed