Java.lang.throwable源代码解析

来源:互联网 发布:java必看书籍知乎 编辑:程序博客网 时间:2024/05/22 07:51

Java.lang.throwable源代码解析  自己留存 学习

package java.lang; import java.io.*; /** * * Throwable是所有Error和Exceptiong的父类 * 注意它有四个构造函数: * Throwable() * Throwable(String message) * Throwable(Throwable cause) * Throwable(String message, Throwable cause) * */ public class Throwable implements Serializable {   private static final long serialVersionUID = -3042686055658047285L;    /**   * Native code saves some indication of the stack backtrace in this slot.   */   private transient Object backtrace;    /**   * 描述此异常的信息   */   private String detailMessage;    /**   * 表示当前异常由那个Throwable引起   * 如果为null表示此异常不是由其他Throwable引起的   * 如果此对象与自己相同,表明此异常的起因对象还没有被初始化   */   private Throwable cause = this;    /**   * 描述异常轨迹的数组   */   private StackTraceElement[] stackTrace;    /**   * 构造函数,起因对象没有被初始化可以在以后使用initCause进行初始化   * fillInStackTrace可以用来初始化它的异常轨迹的数组   */   public Throwable() {    fillInStackTrace();   }    /**   * 构造函数   */   public Throwable(String message) {    //填充异常轨迹数组    fillInStackTrace();    //初始化异常描述信息    detailMessage = message;   }    /**   * 构造函数,cause表示起因对象   */   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;   }    /**   * 获取详细信息   */   public String getMessage() {    return detailMessage;   }    /**   * 获取详细信息   */   public String getLocalizedMessage() {    return getMessage();   }    /**   * 获取起因对象   */   public Throwable getCause() {    return (cause==this ? null : cause);   }    /**   * 初始化起因对象,这个方法只能在未被初始化的情况下调用一次   */   public synchronized Throwable initCause(Throwable cause) {    //如果不是未初始化状态则抛出异常    if (this.cause != this)     throw new IllegalStateException("Can't overwrite cause");       //要设置的起因对象与自身相等则抛出异常    if (cause == this)     throw new IllegalArgumentException("Self-causation not permitted");       //设置起因对象    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);   }    /**   * 打印出错误轨迹   */   public void printStackTrace(PrintStream s) {    synchronized (s) {    //调用当前对象的toString方法     s.println(this);    //获取异常轨迹数组     StackTraceElement[] trace = getOurStackTrace();        //打印出每个元素的字符串表示     for (int i=0; i < trace.length; i++)     s.println("\tat " + trace[i]);     //获取起因对象     Throwable ourCause = getCause();        //递归的打印出起因对象的信息     if (ourCause != null)     ourCause.printStackTraceAsCause(s, trace);    }   }    /**   * 打印起因对象的信息   * @param s 打印的流   * @param causedTrace 有此对象引起的异常的异常轨迹   */   private void printStackTraceAsCause(PrintStream s,            StackTraceElement[] causedTrace)   {    //获得当前的异常轨迹    StackTraceElement[] trace = getOurStackTrace();    //m为当前异常轨迹数组的最后一个元素位置,    //n为当前对象引起的异常的异常轨迹数组的最后一个元素    int m = trace.length-1, n = causedTrace.length-1;    //分别从两个数组的后面做循环,如果相等则一直循环,直到不等或数组到头    while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {     m--; n--;    }       //相同的个数    int framesInCommon = trace.length - 1 - m;       //打印出不同的错误轨迹    s.println("Caused by: " + this);    for (int i=0; i <= m; i++)     s.println("\tat " + trace[i]);    //如果有相同的则打印出相同的个数    if (framesInCommon != 0)     s.println("\t... " + framesInCommon + " more");     //获得此对象的起因对象,并递归打印出信息    Throwable ourCause = getCause();    if (ourCause != null)     ourCause.printStackTraceAsCause(s, trace);   }    /**   * 打印出错误轨迹   */   public void printStackTrace(PrintWriter s) {    synchronized (s) {     s.println(this);     StackTraceElement[] trace = getOurStackTrace();     for (int i=0; i < trace.length; i++)      s.println("\tat " + trace[i]);      Throwable ourCause = getCause();     if (ourCause != null)      ourCause.printStackTraceAsCause(s, trace);    }   }    /**   * 打印起因对象的信息   */   private void printStackTraceAsCause(PrintWriter s,            StackTraceElement[] causedTrace)   {    // assert Thread.holdsLock(s);     // Compute number of frames in common between this and caused    StackTraceElement[] trace = getOurStackTrace();    int m = trace.length-1, n = causedTrace.length-1;    while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {     m--; n--;    }    int framesInCommon = trace.length - 1 - m;     s.println("Caused by: " + this);    for (int i=0; i <= m; i++)     s.println("\tat " + trace[i]);    if (framesInCommon != 0)     s.println("\t... " + framesInCommon + " more");     // Recurse if we have a cause    Throwable ourCause = getCause();    if (ourCause != null)     ourCause.printStackTraceAsCause(s, trace);   }    /**   * 填充异常轨迹   */   public synchronized native Throwable fillInStackTrace();    /**   * 返回当前的异常轨迹的拷贝   */   public StackTraceElement[] getStackTrace() {    return (StackTraceElement[]) getOurStackTrace().clone();   }      /**   * 获取当前的异常轨迹   */   private synchronized StackTraceElement[] getOurStackTrace() {    //如果第一次调用此方法则初始化异常轨迹数组    if (stackTrace == null) {    //获得异常轨迹深度     int depth = getStackTraceDepth();    //创建新的异常轨迹数组,并填充它     stackTrace = new StackTraceElement[depth];        for (int i=0; i < depth; i++)     stackTrace[i] = getStackTraceElement(i);//获取指定位标的异常轨迹    }       return stackTrace;   }    /**   * 设置异常轨迹   */   public void setStackTrace(StackTraceElement[] stackTrace) {    //拷贝设置参数    StackTraceElement[] defensiveCopy =     (StackTraceElement[]) stackTrace.clone();       //如果设置参数有空元素则抛出异常    for (int i = 0; i < defensiveCopy.length; i++)     if (defensiveCopy[i] == null)      throw new NullPointerException("stackTrace[" + i + "]");     //设置当前对象的异常轨迹    this.stackTrace = defensiveCopy;   }    /**   * 异常轨迹的深度,0表示无法获得   */   private native int getStackTraceDepth();    /**   * 获取指定位标的异常轨迹   */   private native StackTraceElement getStackTraceElement(int index);      private synchronized void writeObject(java.io.ObjectOutputStream s)    throws IOException   {    getOurStackTrace();    s.defaultWriteObject();   } } 
原创粉丝点击