【问题标题】:Why is printstacktrace() of exception method does not print to console when ever called?为什么异常方法的 printstacktrace() 在调用时不会打印到控制台?
【发布时间】:2020-01-03 08:10:04
【问题描述】:

每当我们尝试使用printStackTrace() 方法打印堆栈跟踪时,为什么输出不是预期的顺序?假设我们有一些打印语句以及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)

【问题讨论】:

    标签: java printstacktrace


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      来自 Javadoc:

      void printStackTrace​()     
      
      Prints this throwable and its backtrace to the standard error stream.
      

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

      【讨论】:

        【解决方案3】:

        如果您查看不带参数的 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));
        }
        

        这也是documented

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

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

        【讨论】:

          【解决方案4】:

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-01
            • 2023-03-10
            • 1970-01-01
            • 1970-01-01
            • 2020-06-29
            • 2018-04-15
            相关资源
            最近更新 更多