java Throwable源码

http://riddickbryant.iteye.com/blog/444185

 

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

 

你可能感兴趣的:(java,thread,Blog)