javaexceptionstack-overflowbuffered

Understanding the Java stack


There is this code:

public class Main {
    public static void main(final String[] args) throws Exception {
        System.out.print("1");
        doAnything();
        System.out.println("2");
    }

    private static void doAnything() {
        try {
            doAnything();
        } catch (final Error e) {
            System.out.print("y");
        }
    }
}

And there is the output:

1yyyyyyyy2

Why does it print "y" eight times and no more. How can Java call println() when StackOverflowError encountered?


Solution

  • Here you are catching Error and not Exception in which case your program would have crashed.

    If you try this code (modified to add a static counter)

    public class StackError {
    
    static int i = 1;
    
    public static void main(final String[] args) throws Exception {
        System.out.print("1");
        doAnything();
        System.out.println("2");
    }
    
    private static void doAnything() {
        try {
            i++;
    //          System.out.println(i);
            doAnything();
        } catch (Error e) {
            System.out.print("y"+i+"-");
    
        }
    }
    }
    

    Output

     1y6869-2
    

    So, it has got stackerror 6869 times(changes for different runs) and the last value is printed. If you just print the y as you did earlier then it might the case that the output is getting bufferred and not getting flushed as it is not a println.


    Update

    The System.out.println internally calls the PrintStream which is buffered. You don't loose any data from the buffer, it gets all written to the output( terminal in your case) after it fills up, or when you explicitly call flush on it.

    Coming back to this scenario, it depends on the internal dynamics of how much the stack is filled up and how many print statements were able to get executed from the catch in doAnything() and those number of characters were written to the buffer. In the main back it finnally get's printed with the number 2.

    javadoc reference to buffered streams