异常抛出e.printStackTrace();工作原理

时间:2022-05-30 00:45:18

//测试类

public class TestPrintStackTrace {

public static void main(String[] args) {
try {
f();
} catch (Exception e) {
e.printStackTrace();
}

}

public static void f() throws Exception {
throw new Exception("出问题啦!");
}

}


//查看e.printStackTrace();源码

public class Throwable implements Serializable{

//因为System.err是PrintStream类型,所以调用了public void printStackTrace(PrintStream s)函数

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


//此处的s=System.err,构造了WrappedPrintStream(s)后直接走private void printStackTrace(PrintStreamOrWriter s)

public void printStackTrace(PrintStream s) {
        printStackTrace(new WrappedPrintStream(s));
    }

//这里就是e.printStackTrace()实现的底层代码,有些看不懂没事,抓住主干代码看,看他如何抛出异常的

private void printStackTrace(PrintStreamOrWriter s) {
        // Guard against malicious overrides of Throwable.equals by
        // using a Set with identity equality semantics.
        Set<Throwable> dejaVu = Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());

dejaVu.add(this);

        synchronized (s.lock()) {
            // Print our stack trace
            s.println(this);//此处的this是mian方法中的new Exception("出问题啦!"),所以此处默认调用toString方法
                /*public String toString() {
        String s = getClass().getName();
       
  String message = getLocalizedMessage();
       
  return (message != null) ? (s + ": " + message) : s;
    }*/
//toString方法中s=文件名,message=出问题啦!
//形如:异常抛出e.printStackTrace();工作原理
               
           

//此处便是用for循环输出每个出错位置,getOurStackTrace()获取每个出错的位置复制给trace,然后用增强for遍历,到此就是全部过程

StackTraceElement[] trace = getOurStackTrace();
            for (StackTraceElement traceElement : trace)
                s.println("\tat " + traceElement);


            // Print suppressed exceptions, if any
            for (Throwable se : getSuppressed())
                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);


            // Print cause, if any
            Throwable ourCause = getCause();
            if (ourCause != null)
                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
        }
    }



//WrappedPrintStream

private static class WrappedPrintStream extends PrintStreamOrWriter {
        private final PrintStream printStream;

//此处的printStream=System.err
      WrappedPrintStream(PrintStream printStream) {
            this.printStream = printStream;
      }


        Object lock() {
            return printStream;
        }


        void println(Object o) {
            printStream.println(o);
        }
    }

}