Throwable源码分析

package java.lang;
import  java.io.*;
import  java.util.*;


// 
public class Throwable implements Serializable {
    // 
    private static final long serialVersionUID = -3042686055658047285L;
    // 用transient关键字标记的成员变量不参与序列化过程。
    private transient Object backtrace;
    // 存储信息
    private String detailMessage;
    
    private static class SentinelHolder {
        public static final StackTraceElement STACK_TRACE_ELEMENT_SENTINEL =
            new StackTraceElement("", "", null, Integer.MIN_VALUE);
        public static final StackTraceElement[] STACK_TRACE_SENTINEL =
            new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
    }
    private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
    // 存储Throwable信息
    private Throwable cause = this;
    private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
    // 用来存储被抑制的异常
    private static final List<Throwable> SUPPRESSED_SENTINEL =
        Collections.unmodifiableList(new ArrayList<Throwable>(0));
    // 抑制的异常,SUPPRESSED_SENTINEL为static final, 而suppressedExceptions可以改变
    private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
    // 定义几个字段,异常输出时进行拼接。
    private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
    private static final String SELF_SUPPRESSION_MESSAGE = "Self-suppression not permitted";
    private static final String CAUSE_CAPTION = "Caused by: ";
    private static final String SUPPRESSED_CAPTION = "Suppressed: ";
    
    // 构造函数
    public Throwable() {
        // 堆栈信息跟踪
        fillInStackTrace();
    }
    
    // 构造函数
    public Throwable(String message) {
        // 堆栈信息跟踪
        fillInStackTrace();
        // 记录的信息
        detailMessage = message;
    }
    
    // 构造函数
    public Throwable(String message, Throwable cause) {
        // 堆栈信息跟踪
        fillInStackTrace();
        detailMessage = message;
        this.cause = cause;
    }
    
    // 构造函数
    public Throwable(Throwable cause) {
        // 堆栈信息跟踪
        fillInStackTrace();
        detailMessage = (cause==null ? null : cause.toString());
        this.cause = cause;
    }
    
    // 构造函数
    protected Throwable(String message, Throwable cause,
                        boolean enableSuppression,
                        boolean writableStackTrace) {
        // 传入参数,是否进行堆栈跟踪
        if (writableStackTrace) {
            fillInStackTrace();
        } else {
            stackTrace = null;
        }
        detailMessage = message;
        this.cause = cause;
        // 是否启用抑制
        if (!enableSuppression)
            suppressedExceptions = null;
    }
    
    // 返回此throwable的详细消息字符串。
    public String getMessage() {
        return detailMessage;
    }
    
    // 创建此可抛出的本地化描述。 子类可以覆盖此方法,以生成特定于区域的消息。
    public String getLocalizedMessage() {
        return getMessage();
    }
    
    // 抛出可能的原因
    public synchronized Throwable getCause() {
        return (cause==this ? null : cause);
    }
    
    // 将此throwable的原因初始化为指定值
    public synchronized Throwable initCause(Throwable cause) {
        if (this.cause != this)
            throw new IllegalStateException("Can't overwrite cause with " +
                                            Objects.toString(cause, "a null"), this);
        if (cause == this)
            throw new IllegalArgumentException("Self-causation not permitted", this);
        this.cause = cause;
        return this;
    }
    
    // 返回此可抛出的简短描述。
    public String toString() {
        String s = getClass().getName();
        String message = getLocalizedMessage();
        // 类名与可抛的信息
        return (message != null) ? (s + ": " + message) : s;
    }
    
    // 
    public void printStackTrace() {
        printStackTrace(System.err);
    }
    
    // 此方法在错误输出流上为该Throwable对象打印一个堆栈跟踪,该值为字段System.err的值
    public void printStackTrace(PrintStream s) {
        printStackTrace(new WrappedPrintStream(s));
    }
    
    // 打印出错误的信息
    private void printStackTrace(PrintStreamOrWriter s) {
        // 定义一个set集合用于存储错误的信息
        Set<Throwable> dejaVu =
            Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
        // 将当前的错误信息添加进去
        dejaVu.add(this);
        
        // s.lock() 返回printStream打印流对象
        // 即只有对象获到printStream时才能进入下面的同步代码块中
        synchronized (s.lock()) {
            s.println(this);
            // 获取到异常的信息
            StackTraceElement[] trace = getOurStackTrace();
            // 遍历 将异常的信息打印出来。
            for (StackTraceElement traceElement : trace)
                s.println("\tat " + traceElement);
            // 封闭堆栈跟踪
            for (Throwable se : getSuppressed())
                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
            Throwable ourCause = getCause();
            // 
            if (ourCause != null)
                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
        }
    }
    

    private void printEnclosedStackTrace(PrintStreamOrWriter s,
                                         StackTraceElement[] enclosingTrace,
                                         String caption,
                                         String prefix,
                                         Set<Throwable> dejaVu) {
        // assert 断言,不懂这里为什么要加上断言
        assert Thread.holdsLock(s.lock());
        // 异常信息中是否包含当前类的异常
        if (dejaVu.contains(this)) {
            s.println("\t[CIRCULAR REFERENCE:" + this + "]");
        } else {
            // 将当前的信息添加进入到dejaVe中
            dejaVu.add(this);
            // 获取到所有的异常信息
            StackTraceElement[] trace = getOurStackTrace();
            // 异常数组最大的下标
            int m = trace.length - 1;
            int n = enclosingTrace.length - 1;
            while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
                // 找到trace与enclosingTrace不同的下标位置,
                m--; n--;
            }
            // 计算相同之后的剩下元素的个数
            int framesInCommon = trace.length - 1 - m;
            s.println(prefix + caption + this);
            // 将相同的异常信息打印出来。
            for (int i = 0; i <= m; i++)
                s.println(prefix + "\tat " + trace[i]);
            // 剩下元素的个数不为0, 用... 代替
            if (framesInCommon != 0)
                s.println(prefix + "\t... " + framesInCommon + " more");
            // 
            for (Throwable se : getSuppressed())
                // 递归调用,向下查找进一步的异常原因
                // 也就是我们程序报错时,控制台出现的:原因 ——> 异常信息 ——>原因  ——> 异常信息
                se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
                                           prefix +"\t", dejaVu);
            // 获取到异常可能的原因
            Throwable ourCause = getCause();
            if (ourCause != null)
                ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
        }
    }
    
    // 打印异常信息
    public void printStackTrace(PrintWriter s) {
        printStackTrace(new WrappedPrintWriter(s));
    }
    
    // 内部抽象类
    private abstract static class PrintStreamOrWriter {
        abstract Object lock();
        abstract void println(Object o);
    }
    
    // 内部类
    private static class WrappedPrintStream extends PrintStreamOrWriter {
        // 定义一个输出流,拼接传入的流对象
        private final PrintStream printStream;
        
        // 将传入的流赋值给当前的printString
        WrappedPrintStream(PrintStream printStream) {
            this.printStream = printStream;
        }
        
        // 返回printStream
        Object lock() {
            return printStream;
        }
        
        // 将信息打印出来
        void println(Object o) {
            printStream.println(o);
        }
    }
    
    // 内部类,(还没有看IO流,不太懂下面代码的意思)
    private static class WrappedPrintWriter extends PrintStreamOrWriter {
        private final PrintWriter printWriter;
        WrappedPrintWriter(PrintWriter printWriter) {
            this.printWriter = printWriter;
        }
        Object lock() {
            return printWriter;
        }
        void println(Object o) {
            printWriter.println(o);
        }
    }
    
    // 填写执行堆栈跟踪。 该方法记录了此Throwable对象信息,了解当前线程的堆栈帧的当前状态。 
    public synchronized Throwable fillInStackTrace() {
        if (stackTrace != null || backtrace != null ) {
            fillInStackTrace(0);
            stackTrace = UNASSIGNED_STACK;
        }
        return this;
    }
    
    // 本地方法,堆栈信息
    private native Throwable fillInStackTrace(int dummy);
    
    // 
    public StackTraceElement[] getStackTrace() {
        return getOurStackTrace().clone();
    }
    
    // 获取到所有的异常信息
    // 异常的信息存储在stackTrace中
    private synchronized StackTraceElement[] getOurStackTrace() {
        //  添加异常信息的条件(不懂这里代码的意思)
        if (stackTrace == UNASSIGNED_STACK ||
            (stackTrace == null && backtrace != null)) {
            // 获取当前栈的深度
            int depth = getStackTraceDepth();
            // 定义一个stackTraceElement数组,大小为当前对象能到达的深度,
            stackTrace = new StackTraceElement[depth];
            for (int i=0; i < depth; i++)
                // 遍历将异常的信息存在stackce[]中
                stackTrace[i] = getStackTraceElement(i);
        } else if (stackTrace == null) {
            return UNASSIGNED_STACK;
        }
        return stackTrace;
    }
    
    // 设置将被返回的堆栈微量元素getStackTrace()和由印刷printStackTrace()和相关方法
    public void setStackTrace(StackTraceElement[] stackTrace) {
        StackTraceElement[] defensiveCopy = stackTrace.clone();
        // 遍历堆栈信息是否需要抛异常
        for (int i = 0; i < defensiveCopy.length; i++) {
            // 如果stackTrace是 null,或者如果任何的元件的 stackTrace是 null,就报NullPointerException
            if (defensiveCopy[i] == null)
                throw new NullPointerException("stackTrace[" + i + "]");
        }

        synchronized (this) {
            if (this.stackTrace == null && // 不变的堆栈
                backtrace == null) // Test for out of protocol state
                return;
            // 将
            this.stackTrace = defensiveCopy;
        }
    }
    
    // 获取到栈的深度
    native int getStackTraceDepth();
    
    // 返回堆栈跟踪的指定元素。
    native StackTraceElement getStackTraceElement(int index);

    // 私有方法,在这个类的其它地方没有使用到,不知道什么意思
    private void readObject(ObjectInputStream s)
        throws IOException, ClassNotFoundException {
        s.defaultReadObject();     // read in all fields
        if (suppressedExceptions != null) {
            List<Throwable> suppressed = null;
            if (suppressedExceptions.isEmpty()) {
                suppressed = SUPPRESSED_SENTINEL;
            } else { // Copy Throwables to new list
                suppressed = new ArrayList<>(1);
                for (Throwable t : suppressedExceptions) {
                    if (t == null)
                        throw new NullPointerException(NULL_CAUSE_MESSAGE);
                    if (t == this)
                        throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
                    suppressed.add(t);
                }
            }
            suppressedExceptions = suppressed;
        }
        if (stackTrace != null) {
            if (stackTrace.length == 0) {
                stackTrace = UNASSIGNED_STACK.clone();
            }  else if (stackTrace.length == 1 &&
                        SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
                stackTrace = null;
            } else {
                for(StackTraceElement ste : stackTrace) {
                    if (ste == null)
                        throw new NullPointerException("null StackTraceElement in serial stream. ");
                }
            }
        } else {
            stackTrace = UNASSIGNED_STACK.clone();
        }
    }
    
    // 私有方法,在这个类的其它地方没有使用到,不知道什么意思
    private synchronized void writeObject(ObjectOutputStream s)
        throws IOException {
        getOurStackTrace();
        StackTraceElement[] oldStackTrace = stackTrace;
        try {
            if (stackTrace == null)
                stackTrace = SentinelHolder.STACK_TRACE_SENTINEL;
            s.defaultWriteObject();
        } finally {
            stackTrace = oldStackTrace;
        }
    }
    
    // 将指定的异常附加到为了传递此异常而被抑制的异常
    public final synchronized void addSuppressed(Throwable exception) {
        // 指定的异常与当前的异常不相同
        if (exception == this)
            throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE, exception);
        // 指定的异常为空,
        if (exception == null)
            throw new NullPointerException(NULL_CAUSE_MESSAGE);
        // 没有异常?
        if (suppressedExceptions == null) // Suppressed exceptions not recorded
            return;
        // 
        if (suppressedExceptions == SUPPRESSED_SENTINEL)
            suppressedExceptions = new ArrayList<>(1);
        // 将当前的异常添加进入supperssedEx
        suppressedExceptions.add(exception);
    }
    
    // 定义一个空的可抛变量,抑制的异常为空时,就将这个返回
    private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];

    // 一个数组,其中包含所有被抑制以提供此异常的异常。
    public final synchronized Throwable[] getSuppressed() {
        // 如果抑制的异常为空,那么就返回空的异常数组
        if (suppressedExceptions == SUPPRESSED_SENTINEL ||
            suppressedExceptions == null)
            return EMPTY_THROWABLE_ARRAY;
        else
            // 如果抑制异常数据不为空,那么就将数组转成集合返回回去。
            return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值