简体   繁体   中英

Why is printstacktrace() of exception method does not print to console when ever called?

Whenever we are trying to print stack trace using printStackTrace() method, why the output is not in expected order? suppose we have some print statements along with printStackTrace() and the output is not in expected order.

public class Main {

    public static void main(String[] args) {
        Main m = new Main();
        m.test1();
        System.out.println("main method");
    }

    public void test1() {
        System.out.println(test2());
        System.out.println("test1");
    }

    public int test2() {
        try {
            throw new Exception();
        } catch (Exception e) {
            System.out.println("exception");
            e.printStackTrace();
        } finally {

    }
    return 2;
}

}

Expected output should be :

exception

java.lang.Exception

at com.infor.jdbc.Main.test2(Main.java:18)

at com.infor.jdbc.Main.test1(Main.java:12)

at com.infor.jdbc.Main.main(Main.java:7)

2

test1

main method

But actual result is:

exception

java.lang.Exception          //from printStackTrace

2

test1

main method

at com.infor.jdbc.Main.test2(Main.java:18)  //from printStackTrace

at com.infor.jdbc.Main.test1(Main.java:12)

at com.infor.jdbc.Main.main(Main.java:7)

From the Javadoc:

void printStackTrace​()     

Prints this throwable and its backtrace to the standard error stream.

Notice it says standard error stream . Your System.out.println(...) statements write to standard output , which is a different stream. How they appear interleaved on the console is a function of the operating system and how the streams are buffered. Either output is "correct".

Buffered outputstreams are being written to two separate output(s) without flushing ("stderr" and "stdout"). Print your message, print the stack trace and then flush and you will see the behavior you expected.

public int test2() {
    try {
        throw new Exception();
    } catch (Exception e) {
        System.err.println("exception");
        e.printStackTrace(System.err);
        System.err.flush();
    } finally {

    }
    return 2;
}

If you look at the printStackTrace overload that takes no argument, you'll see that it calls the overload that takes a PrintStream argument, with System.err :

public void printStackTrace() {
    printStackTrace(System.err);
}

/**
 * Prints this throwable and its backtrace to the specified print stream.
 *
 * @param s {@code PrintStream} to use for output
 */
public void printStackTrace(PrintStream s) {
    printStackTrace(new WrappedPrintStream(s));
}

This is also documented .

On the other hand, you are printing your output on the standard output stream, System.out . These are two different streams, and they will kind of both print to the console "in parallel". Sometimes one takes over, sometimes the other does, hence the output you see.

If you call printStackTrace(System.out) , you'll see the expected output.

printstacktrace() method (by default) outputs to the error stream.

By default, error stream is the same as console (std out is also the console by default).

Since you don't have a locking mechanism (OS does not care if they interleave), the outputs from printstacktrace and stdout interleave.

Try e.printstacktrace(System.out) ... and you will see them in expected order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM