Throwable
/**
* Java 語言中所有錯誤和異常的基類,此類及其子類才能通過 throws 被 JVM 虛擬機拋出。
* @since 1.0
*/
public class Throwable implements Serializable {
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -3042686055658047285L;
/**
* JVM 會保存一些棧回溯信息到此對象上
*/
private transient Object backtrace;
/**
* 異常的細節信息
*/
private String detailMessage;
/**
* 共享的空堆棧信息
*/
private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
/**
* 引起此 Throwable 拋出的源 Throwable 對象
* @since 1.4
*/
private Throwable cause = this;
/**
* 此 Throwable 關聯的堆棧信息
* @serial
* @since 1.4
*/
private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
/**
* 棧回溯的深度
*/
private transient int depth;
// Setting this static field introduces an acceptable
// initialization dependency on a few java.util classes.
private static final List<Throwable> SUPPRESSED_SENTINEL = Collections.emptyList();
/**
* 被抑制的異常對象列表
* @serial
* @since 1.7
*/
private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
/** 用於抑制空指針異常的消息 */
private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
/** Message for trying to suppress oneself. */
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: ";
/**
* 創建一個無描述信息的 Throwable 對象
*/
public Throwable() {
fillInStackTrace();
}
/**
* 創建一個持有指定描述信息 message 的 Throwable 對象
* @param message 詳細的信息
*/
public Throwable(String message) {
fillInStackTrace();
detailMessage = message;
}
/**
* 創建一個持有詳細信息和異常來源的 Throwable 對象
* @param message 詳細描述信息
* @param cause 引起此 Throwable 的源 Throwable 對象
* @since 1.4
*/
public Throwable(String message, Throwable cause) {
fillInStackTrace();
detailMessage = message;
this.cause = cause;
}
/**
* 創建一個持有源 Throwable 實例的 Throwable 對象
*
* @param cause 源 Throwable 對象
* @since 1.4
*/
public Throwable(Throwable cause) {
fillInStackTrace();
detailMessage = cause==null ? null : cause.toString();
this.cause = cause;
}
/**
* 填充此 Throwable 實例的堆棧跟蹤信息
*/
public synchronized Throwable fillInStackTrace() {
if (stackTrace != null ||
backtrace != null /* Out of protocol state */ ) {
fillInStackTrace(0);
stackTrace = UNASSIGNED_STACK;
}
return this;
}
private native Throwable fillInStackTrace(int dummy);
/**
* 將異常堆棧信息輸出到標準錯誤流
*/
public void printStackTrace() {
printStackTrace(System.err);
}
/**
* 將此 Throwable 的堆棧信息輸出到指定的 PrintStream s 中
*
* @param s 用於輸出的目標 {@code PrintStream}
*/
public void printStackTrace(PrintStream s) {
printStackTrace(new WrappedPrintStream(s));
}
private void printStackTrace(PrintStreamOrWriter s) {
final Set<Throwable> dejaVu = Collections.newSetFromMap(new IdentityHashMap<>());
dejaVu.add(this);
synchronized (s.lock()) {
// 打印此 Throwable 的信息
s.println(this);
// 打印相關的堆棧信息
final StackTraceElement[] trace = getOurStackTrace();
for (final StackTraceElement traceElement : trace) {
s.println("\tat " + traceElement);
}
// 打印抑制的異常信息
for (final Throwable se : getSuppressed()) {
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
}
// 打印異常原因
final Throwable ourCause = getCause();
if (ourCause != null) {
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
}
}
}
/**
* 將此 Throwable 的堆棧信息打印到 PrintWriter s 中
*
* @param s 用於輸出的 {@code PrintWriter}
* @since 1.1
*/
public void printStackTrace(PrintWriter s) {
printStackTrace(new WrappedPrintWriter(s));
}
/**
* 封裝 PrintStream and PrintWriter
*/
private abstract static class PrintStreamOrWriter {
/** Returns the object to be locked when using this StreamOrWriter */
abstract Object lock();
/** Prints the specified string as a line on this StreamOrWriter */
abstract void println(Object o);
}
private static class WrappedPrintStream extends PrintStreamOrWriter {
private final PrintStream printStream;
WrappedPrintStream(PrintStream printStream) {
this.printStream = printStream;
}
@Override
Object lock() {
return printStream;
}
@Override
void println(Object o) {
printStream.println(o);
}
}
private static class WrappedPrintWriter extends PrintStreamOrWriter {
private final PrintWriter printWriter;
WrappedPrintWriter(PrintWriter printWriter) {
this.printWriter = printWriter;
}
@Override
Object lock() {
return printWriter;
}
@Override
void println(Object o) {
printWriter.println(o);
}
}