5

I was just trying something with try-catch and this code:

public class MainThread
{
    public static void main(String [] args) 
    {
        try 
        {
            badMethod();  
            System.out.print("A"); 
        }  
        catch (Exception ex) 
        {
            System.out.print("B");  
        } 
        finally 
        {
            System.out.print("C"); 
        } 
        System.out.print("D"); 
    }  
    public static void badMethod() 
    {
        throw new Error(); /* Line 22 */
    } 
}

I understand Error will not be caught by the catch block above, but the finally block will be executed, and then the JVM will terminate.

But when I try to run the program many times, I get different outputs:

C printed before the stack trace:

CException in thread "main" java.lang.Error
  at MainThread.badMethod(MainThread.java:22)
  at MainThread.main(MainThread.java:7)

or C printed after the stack trace:

Exception in thread "main" java.lang.Error
  at MainThread.badMethod(MainThread.java:22)
  at MainThread.main(MainThread.java:7)
C

Can anyone explain this behavior?

4

2 回答 2

11

The System.out stream and the System.err stream are separate streams which both have the same output. As such there is a race between them and which "wins" cannot be determined in advance.

As Luiggi Mendoza says;

In order to get the desired result, OP just have to change System.out.print to System.error.print or catch the Error and print it using e.printStacktrace(System.out). Or even better, use a logger that handles all this work for you

It is additionally worth noting that your catch statement does not catch this new Error() because Error!=Exception

于 2013-10-28T14:24:36.407 回答
1

Change

    catch (Exception ex) 

into

    catch (Throwable ex) 

which catches more (Throwable being the base class). It also catches the stack trace in badMethod, which probably does e.printStacktrace(), which calls e.printStacktrace(System.err). Exception is for checked Exception, not RuntimeExceptions.

To the console both writers (PrintStreams), System.out and System.err are written simultaneous, in different threads: so really mixed up.

于 2013-10-28T14:41:53.983 回答