0

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)
4

4 回答 4

4

来自 Javadoc:

void printStackTrace​()     

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

注意它说的是标准错误流。您的System.out.println(...)语句写入标准输出,这是一个不同的流。它们在控制台上的交错显示方式取决于操作系统以及流的缓冲方式。任一输出都是“正确的”。

于 2019-08-30T04:34:35.893 回答
4

缓冲的输出流被写入两个单独的输出而不刷新(“stderr”和“stdout”)。打印您的消息,打印堆栈跟踪,然后刷新,您将看到您预期的行为。

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

    }
    return 2;
}
于 2019-08-30T04:35:40.213 回答
2

如果您查看printStackTrace不带参数的重载,您会看到它调用带PrintStream参数的重载,其中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));
}

这也被记录在案

另一方面,您正在标准输出流上打印输出,System.out. 这是两个不同的流,它们都会“并行”打印到控制台。有时一个接管,有时另一个接管,因此您会看到输出。

如果您调用printStackTrace(System.out),您将看到预期的输出。

于 2019-08-30T04:37:56.653 回答
0

printstacktrace()方法(默认)输出到错误流。

默认情况下,错误流与控制台相同(标准输出默认也是控制台)。

由于您没有锁定机制(操作系统不关心它们是否交错),因此 printstacktrace 和 stdout 的输出交错。

试试e.printstacktrace(System.out)……你会按照预期的顺序看到它们。

于 2019-08-30T04:35:15.593 回答