簡體   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