3

I tried to figure out execution order of try-catch-finally in java. I thought execution order should be

  1. try
  2. catch (if error occurred/ exception caught)
  3. finally (whether exception caught or not)

But I am confused with the result of the following

public class TryCatchFinally {
static int i = 0;
public static void main(String[] args) {
    try {
        System.out.println(i++);
        main(args);
    } catch (StackOverflowError e) {
        System.out.println("Catch");
    } finally {
        System.out.println("Finally");
    }
 }
}

Out put(part of an out put)

9127
9128
9129
9130
CatcFCatch // what is the wrong here???
Finally
Finally // there are more Finally printed here.

My question is what is really happening here?

Let me add more why it is not printing "Catch"???

I am getting this out put when run this in IntelliJ IDEA. But when I run in terminal I am getting out put as follows.

9151
9152
9153
9154CatchFinallyCatch
Finally
Finally
Finally
Finally
Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
  • @MarounMaroun yes, But I want to figure it out what happen really here? – Ruchira Gayan Ranaweera Nov 06 '13 at 10:07
  • You get a bunch of "Finally" printed because as you finish executing every recursive call, the stack is unpiled and all the finally blocks are executed. As for the weird "CatcFCatch" I'm not to sure but I suspect it is probably because `System.out.println` when called at the bottom of the stack is causing more `StackOverflowError` that are being catched at a higher recursive call. – Francis Nov 06 '13 at 10:11
  • 2
    [This](http://stackoverflow.com/questions/18311305/confusing-output-from-infinite-recursion-within-try-catch) might answer your question. – Maroun Nov 06 '13 at 10:11
  • @DavidWallace : its not a typo , i get it too – Hussain Akhtar Wahid 'Ghouri' Nov 06 '13 at 10:12
  • 2
    @Maroun - interesting that the question you linked to was asked by the same person. – Dawood ibn Kareem Nov 06 '13 at 10:14
  • @DavidWallace try this code your self. you will get the same out put. why it is not printing "Catch"? yes that is my question – Ruchira Gayan Ranaweera Nov 06 '13 at 10:14
  • 3
    @Ruchira: this is *pretty much* the same question you already asked in August (linked to by Maroun Maroun). – Joachim Sauer Nov 06 '13 at 10:16

3 Answers3

7

Chances are that you get a stackoverflow error somewhere inside the println call (possibly because some flushing is going on or something similar), leaving the println method in a inconsistent state (having printed part of what it was supposed to).

That can easily happen when you're already handling a StackOverflowError, because at that point you're already dangerously close to an overflowing stack (since you just recovered from one at a point very close to the problem).

My interpretation looks something like this:

  • main calls itself recursively a lot ...
  • you call main for the 9130th time recursively
  • it prints that number
  • it calls itself for the 9131st time
  • it tries to print that number, but throws a StackOverflowError, since the stack is full
  • you enter the catch and try to print "Catch"
  • during that println call another StackOverflowError happens
  • the finally block is executed, because the catch block completed (abruptly)
  • it tries to print "Finally"
  • during that println call yet another StackOverflowError happens
  • that StackOverflowError is caught in the 9130th invocation of main
  • it prints "Catch" (sucessfully, because the stack is now 1 element shorter!)
  • the finally-block is executed and prints Finally successfully, because the stack is now 1 element shorter.
  • more finally blocks execute.
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • I think OP found stack-overflow in `println` what version of Java does he use? – 0x90 Nov 06 '13 at 10:09
  • @0x90 not really relevant, I think. Inside `println`, there are loads of method calls, any one of which could trigger a stack overflow. This applies to very many methods of the Java API. It's not really a bug; it's just the way things work. – Dawood ibn Kareem Nov 06 '13 at 10:30
1

That is because of recursive calls to main. So as you are calling main in main, you are entering multiple times the try catch block, and you are returning from it the same amount of times as you ented it after first StackOverflow occurence. This is the reason on multiple finnalies.

EDIT: As I saw some downvotes, without any reasonable explanation, if someone thinks I'm wrong, just print the damn i counter with decrementaion in finally block.

public static void main(String[] args) {
    try {
        System.out.println(i++);
        main(args);
    } catch (StackOverflowError e) {
        System.out.println("Catch");
    } finally {
        System.out.println("Finally: "+ (i--));
    }
 }
Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

Are you using an IDE (eclipse or similar), if yes then it could be due to that.

Here is the result of my attempt -

// Code

public static void main(String[] args) throws IOException {

    File file = new File("resources/ouput.txt");
    file.createNewFile();
    PrintStream printStream = new PrintStream(file);
    System.setOut(printStream);

    overflowTester(0);

}

private static void overflowTester(int index) {
    try {
        System.out.println(index++);
        overflowTester(index);
    } catch (StackOverflowError  e) {
        System.out.println("Catch");
    } finally {
        System.out.println("Finally");
    }
}

// Output

0
1
2
3
4
5
6
7
8
9
10
...
...
...
9666
Catch
Finally
...
...
Finally

Note: '9666' was printed on the 9667th line and the last Finally was on the 19336th line.

In my case, running the following program :

private static int index = 0;

public static void main(String[] args) throws IOException {

    try {
        System.out.println(index++);
        main(args);
    } catch (StackOverflowError  e) {
        System.out.println("Catch");
    } finally {
        System.out.println("Finally");
    }

}

from the command-prompt, yielded similar result :

0
1
2
3
4
5
...
...
9667
Catch
Finally
...
...
Finally

with '9667' being printed on the 9668th line and the last 'Finally' being printed on the 19338th line.

Ravindra HV
  • 2,558
  • 1
  • 17
  • 26