繁体   English   中英

为什么调用异常方法的printstacktrace()不会打印到控制台?

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

每当我们尝试使用printStackTrace()方法打印堆栈跟踪时,为什么输出的顺序不正确? 假设我们有一些print语句以及printStackTrace() ,并且输出的顺序不正确。

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;
}

}

预期输出应为:

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

但是实际结果是:

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)

从Javadoc:

void printStackTrace​()     

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

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

缓冲的输出流将被写入两个单独的输出,而不会刷新(“ 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;
}

如果查看不带参数的printStackTrace重载,您会发现它使用System.err调用了带PrintStream参数的重载:

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) ,则会看到预期的输出。

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

默认情况下,错误流与控制台相同(默认情况下,std out也是控制台)。

由于您没有锁定机制(OS不在乎它们是否交错),因此printstacktrace和stdout的输出会交错。

尝试e.printstacktrace(System.out) ...,您会看到它们的预期顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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