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