Confusing output from infinite recursion within try-catch
Solution 1:
Note the absence of newline characters in 433943394339
. It indicates that something wrong happens inside System.out.println()
.
The essential point here is that System.out.println()
requires some stack space to work, so that StackOverflowError
is thrown from System.out.println()
.
Here is your code with marked points:
public static void main(String[] args) {
try{
System.out.println(i); // (1)
i++;
main(args); // (2)
}catch (StackOverflowError e){
System.out.println(i); // (3)
i++;
main(args); // (4)
}
}
Let's imagine what happens at level N of recursion when i = 4338
:
- Statement (1) at level N prints
4338
. Output4338\n
-
i
is incremented to4339
- Control flow enters level N + 1 at (2)
- Statement (1) at level N + 1 tries to print
4339
, butSystem.out.println()
throws aStackOverflowError
before it prints a newline. Output4339
-
StackOverflowError
is caught at level N + 1, statement (3) tries to print4339
and fails for the same reason again. Output4339
- Exception is caught at level N. At this point there is more stack space available, therefore statement (3) tries to print
4339
and succeeds (newline is printed correctly). Output4339\n
-
i
is incremented and control flow enters level N + 1 again at (4)
After this point the situation repeats with 4340
.
I'm not sure why some numbers are printed correclty between sequences without newlines, perhaps its related to internal work of System.out.println()
and buffers it uses.
Solution 2:
What I suspect being happening is this:
- Print i
- Print newline
- Increase i
- Enter main
- Print i
- Print newline
- Increase i
- Enter main
- Print i
- StackOverflow got thrown (instead of print newline)
- Return to main, now in the catch
- Print i
- StackOverflow got thrown again (instead of print newline)
- Return to main, in another catch body.
- Print i
- Print newline (now doesn't fail anymore, because we are two levels higher)
- Enter main, and go back to 1.
Solution 3:
According to my test:
When Exception is thrown by try Block, i
has same value when it comes in catch block (as its not incremented due to exception)
and then inside catch block same exception is thrown and which is again caught by catch block !
I tried Following Code
try {
System.out.println("Try " + i);
i++;
main(args);
} catch (StackOverflowError e) {
System.out.println("\nBefore");
System.out.println("Catch " + i);
i++;
System.out.println("After");
main(args);
}
Output :
Try 28343
Try 28344
Before
Before
Before
Before
Catch 28344
After
Try 28345
Try 28346
Try 28347
Try 28348
Before
Before
Before
Before
Catch 28348
After
Try 28349
when try block throws exception it is caught by catch block but when it goes to System.out.println("Catch " + i);
again Exception is thrown 4 times (in my eclipse) Without printing System.out.println("Catch " + i);
As in above output, i have tested it by printing "Before" Text which is printed four times before it prints System.out.println("Catch " + i);
Solution 4:
If the execution of println
(or one of the methods called by it) causes a stack overflow, you will print the same i
value from the catch clause of the enclosing main
incarnation.
The exact behavior is rather unpredictable as it depends on the stack space still available.