1

To my understanding following code should print 0 as output because stack is full and it should get out of method immediately.

However when I ran the following code it is printing 100 for first case and prints 1 for second case:

class ErrorAndException {
        public static int callStackOverflow() {
            try {
                callStackOverflow();
                return 100;
            } catch (Error e) {
                System.out.println(e);
                return 0;
            } finally {
            }
        }

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

Case - 2

class ErrorAndException {
            public static int callStackOverflow() {
                try {
                    callStackOverflow();
                    return 100;
                } catch (Error e) {
                    System.out.println(e);
                    return 0;
                } finally {
                           return 1
                }
            }

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

Please help me understand this behavior.

T-Bag
  • 10,916
  • 3
  • 54
  • 118

2 Answers2

5

Only the final call to callStackOverflow() (the one in which StackOverflowError is thrown) returns 0. But when it returns, the previous calls to callStackOverflow() all return 100. Your main method prints just the value returned by the initial call to callStackOverflow(), which is 100.

If you want the 0 to be returned to the main method, callStackOverflow() would have to return the value returned by the recursive call:

public static int callStackOverflow() {
    try {
        return callStackOverflow();
    } catch (Error e) {
        System.out.println(e);
        return 0;
    } finally {
    }
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • Does this mean on stack overflow error , JVM will perform complete stack unwind until it reaches to first call, I was thinking program will terminate from last call only – T-Bag Apr 14 '19 at 14:41
  • @ShowStopper why would you think that? The stack still contains all the previous calls to `callStackOverflow()`, so they must be unwound before the `main` method is reached. – Eran Apr 14 '19 at 14:43
  • thanks a lot, one more thing I have edited my question it is printing 1 if I put return statement in finally, please help me understand this as well, in this case stack unwinding is not performed ? – T-Bag Apr 14 '19 at 14:46
  • @ShowStopper `finally` is executed regardless if an exception was thrown by the try clause or not, and regardless of whether such as exception was caught by the catch clause. Therefore if you put a `return 1;` statement in the finally clause, 1 will always be returned. Unwinding is still performed, but all the recursive calls of your method return 1. – Eran Apr 14 '19 at 14:49
  • It seems to be a common expectation that a return executed from a recursive call that's 'N' levels deep will someone magically effect a return from the very first entry into the function. –  Apr 14 '19 at 17:07
3

The final item that causes the overflow will return 0 to the previous instance, but that value is lost as all lower instances just return 100 to one another until the final instance exits returning 100.

Cubius
  • 91
  • 5