java Throwable源码

  1. package java.lang;     
  2. import java.io.*;     
  3. /**   
  4. *    
  5. * Throwable是所有Error和Exceptiong的父类   
  6. * 注意它有四个构造函数:   
  7. * Throwable()   
  8. * Throwable(String message)   
  9. * Throwable(Throwable cause)   
  10. * Throwable(String message, Throwable cause)   
  11. *    
  12. */    
  13. public class Throwable implements Serializable {     
  14.       private static final long serialVersionUID = -3042686055658047285L;     
  15.     
  16.       /**   
  17.        * Native code saves some indication of the stack backtrace in this slot.   
  18.        */    
  19.       private transient Object backtrace;      
  20.     
  21.       /**   
  22.        * 描述此异常的信息   
  23.        */    
  24.       private String detailMessage;     
  25.     
  26.       /**   
  27.        * 表示当前异常由那个Throwable引起   
  28.         * 如果为null表示此异常不是由其他Throwable引起的   
  29.         * 如果此对象与自己相同,表明此异常的起因对象还没有被初始化   
  30.        */    
  31.       private Throwable cause = this;     
  32.     
  33.       /**   
  34.        * 描述异常轨迹的数组   
  35.        */    
  36.       private StackTraceElement[] stackTrace;     
  37.     
  38.       /**   
  39.        * 构造函数,起因对象没有被初始化可以在以后使用initCause进行初始化   
  40.         * fillInStackTrace可以用来初始化它的异常轨迹的数组   
  41.        */    
  42.       public Throwable() {     
  43.           fillInStackTrace();     
  44.       }     
  45.     
  46.       /**   
  47.        * 构造函数   
  48.        */    
  49.       public Throwable(String message) {     
  50.          //填充异常轨迹数组     
  51.           fillInStackTrace();     
  52.          //初始化异常描述信息     
  53.           detailMessage = message;     
  54.       }     
  55.     
  56.       /**   
  57.        * 构造函数,cause表示起因对象   
  58.        */    
  59.       public Throwable(String message, Throwable cause) {     
  60.           fillInStackTrace();     
  61.           detailMessage = message;     
  62.           this.cause = cause;     
  63.       }     
  64.     
  65.       /**   
  66.        * 构造函数   
  67.        */    
  68.       public Throwable(Throwable cause) {     
  69.           fillInStackTrace();     
  70.           detailMessage = (cause==null ? null : cause.toString());     
  71.           this.cause = cause;     
  72.       }     
  73.     
  74.       /**   
  75.        * 获取详细信息   
  76.        */    
  77.       public String getMessage() {     
  78.           return detailMessage;     
  79.       }     
  80.     
  81.       /**   
  82.        * 获取详细信息   
  83.        */    
  84.       public String getLocalizedMessage() {     
  85.           return getMessage();     
  86.       }     
  87.     
  88.       /**   
  89.        * 获取起因对象   
  90.        */    
  91.       public Throwable getCause() {     
  92.           return (cause==this ? null : cause);     
  93.       }     
  94.     
  95.       /**   
  96.        * 初始化起因对象,这个方法只能在未被初始化的情况下调用一次   
  97.        */    
  98.       public synchronized Throwable initCause(Throwable cause) {     
  99.          //如果不是未初始化状态则抛出异常     
  100.           if (this.cause != this)     
  101.               throw new IllegalStateException("Can't overwrite cause");     
  102.              
  103.          //要设置的起因对象与自身相等则抛出异常     
  104.           if (cause == this)     
  105.               throw new IllegalArgumentException("Self-causation not permitted");     
  106.              
  107.          //设置起因对象     
  108.           this.cause = cause;     
  109.          //返回设置的起因的对象     
  110.           return this;     
  111.       }     
  112.     
  113.       /**   
  114.        * 字符串表示形式   
  115.        */    
  116.       public String toString() {          
  117.           String s = getClass().getName();             
  118.           String message = getLocalizedMessage();           
  119.           return (message != null) ? (s + ": " + message) : s;     
  120.       }     
  121.     
  122.       /**   
  123.        * 打印出错误轨迹   
  124.        */    
  125.       public void printStackTrace() {      
  126.           printStackTrace(System.err);     
  127.       }     
  128.     
  129.       /**   
  130.        * 打印出错误轨迹   
  131.        */    
  132.       public void printStackTrace(PrintStream s) {     
  133.           synchronized (s) {     
  134.             //调用当前对象的toString方法     
  135.               s.println(this);     
  136.             //获取异常轨迹数组     
  137.               StackTraceElement[] trace = getOurStackTrace();     
  138.                  
  139.             //打印出每个元素的字符串表示     
  140.               for (int i=0; i < trace.length; i++)     
  141.                 s.println("\tat " + trace[i]);     
  142.     
  143.             //获取起因对象     
  144.               Throwable ourCause = getCause();     
  145.                  
  146.             //递归的打印出起因对象的信息     
  147.               if (ourCause != null)     
  148.                 ourCause.printStackTraceAsCause(s, trace);     
  149.           }     
  150.       }     
  151.     
  152.       /**   
  153.        * 打印起因对象的信息   
  154.        * @param s 打印的流   
  155.         * @param causedTrace 有此对象引起的异常的异常轨迹    
  156.        */    
  157.       private void printStackTraceAsCause(PrintStream s,     
  158.                                           StackTraceElement[] causedTrace)     
  159.       {     
  160.          //获得当前的异常轨迹     
  161.           StackTraceElement[] trace = getOurStackTrace();     
  162.          //m为当前异常轨迹数组的最后一个元素位置,      
  163.          //n为当前对象引起的异常的异常轨迹数组的最后一个元素     
  164.           int m = trace.length-1, n = causedTrace.length-1;     
  165.          //分别从两个数组的后面做循环,如果相等则一直循环,直到不等或数组到头     
  166.           while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {     
  167.               m--; n--;     
  168.          }     
  169.              
  170.          //相同的个数     
  171.           int framesInCommon = trace.length - 1 - m;     
  172.              
  173.          //打印出不同的错误轨迹     
  174.           s.println("Caused by: " + this);     
  175.           for (int i=0; i <= m; i++)     
  176.               s.println("\tat " + trace[i]);     
  177.           //如果有相同的则打印出相同的个数     
  178.           if (framesInCommon != 0)     
  179.               s.println("\t... " + framesInCommon + " more");     
  180.     
  181.          //获得此对象的起因对象,并递归打印出信息     
  182.           Throwable ourCause = getCause();     
  183.           if (ourCause != null)     
  184.               ourCause.printStackTraceAsCause(s, trace);     
  185.       }     
  186.     
  187.       /**   
  188.        * 打印出错误轨迹   
  189.        */    
  190.       public void printStackTrace(PrintWriter s) {      
  191.           synchronized (s) {     
  192.               s.println(this);     
  193.               StackTraceElement[] trace = getOurStackTrace();     
  194.               for (int i=0; i < trace.length; i++)     
  195.                   s.println("\tat " + trace[i]);     
  196.     
  197.               Throwable ourCause = getCause();     
  198.               if (ourCause != null)     
  199.                   ourCause.printStackTraceAsCause(s, trace);     
  200.           }     
  201.       }     
  202.     
  203.       /**   
  204.        * 打印起因对象的信息   
  205.         */    
  206.       private void printStackTraceAsCause(PrintWriter s,     
  207.                                           StackTraceElement[] causedTrace)     
  208.       {     
  209.           // assert Thread.holdsLock(s);     
  210.     
  211.           // Compute number of frames in common between this and caused     
  212.           StackTraceElement[] trace = getOurStackTrace();     
  213.           int m = trace.length-1, n = causedTrace.length-1;     
  214.           while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {     
  215.               m--; n--;     
  216.           }     
  217.           int framesInCommon = trace.length - 1 - m;     
  218.     
  219.           s.println("Caused by: " + this);     
  220.           for (int i=0; i <= m; i++)     
  221.               s.println("\tat " + trace[i]);     
  222.           if (framesInCommon != 0)     
  223.               s.println("\t... " + framesInCommon + " more");     
  224.     
  225.           // Recurse if we have a cause     
  226.           Throwable ourCause = getCause();     
  227.           if (ourCause != null)     
  228.               ourCause.printStackTraceAsCause(s, trace);     
  229.       }     
  230.     
  231.       /**   
  232.        * 填充异常轨迹   
  233.        */    
  234.       public synchronized native Throwable fillInStackTrace();     
  235.     
  236.       /**   
  237.        * 返回当前的异常轨迹的拷贝   
  238.        */    
  239.       public StackTraceElement[] getStackTrace() {     
  240.           return (StackTraceElement[]) getOurStackTrace().clone();     
  241.       }     
  242.     
  243.          
  244.       /**   
  245.        * 获取当前的异常轨迹   
  246.         */    
  247.       private synchronized StackTraceElement[] getOurStackTrace() {     
  248.          //如果第一次调用此方法则初始化异常轨迹数组     
  249.           if (stackTrace == null) {     
  250.             //获得异常轨迹深度     
  251.               int depth = getStackTraceDepth();     
  252.             //创建新的异常轨迹数组,并填充它     
  253.               stackTrace = new StackTraceElement[depth];     
  254.                  
  255.             for (int i=0; i < depth; i++)     
  256.                 stackTrace[i] = getStackTraceElement(i);//获取指定位标的异常轨迹     
  257.           }     
  258.              
  259.           return stackTrace;     
  260.       }     
  261.     
  262.       /**   
  263.        * 设置异常轨迹   
  264.        */    
  265.       public void setStackTrace(StackTraceElement[] stackTrace) {     
  266.          //拷贝设置参数     
  267.           StackTraceElement[] defensiveCopy =     
  268.               (StackTraceElement[]) stackTrace.clone();     
  269.              
  270.          //如果设置参数有空元素则抛出异常     
  271.           for (int i = 0; i < defensiveCopy.length; i++)     
  272.               if (defensiveCopy[i] == null)     
  273.                   throw new NullPointerException("stackTrace[" + i + "]");     
  274.     
  275.          //设置当前对象的异常轨迹     
  276.           this.stackTrace = defensiveCopy;     
  277.       }     
  278.     
  279.       /**   
  280.        * 异常轨迹的深度,0表示无法获得   
  281.        */    
  282.       private native int getStackTraceDepth();     
  283.     
  284.       /**   
  285.        * 获取指定位标的异常轨迹   
  286.        */    
  287.       private native StackTraceElement getStackTraceElement(int index);     
  288.     
  289.          
  290.       private synchronized void writeObject(java.io.ObjectOutputStream s)     
  291.           throws IOException     
  292.       {     
  293.           getOurStackTrace();     
  294.           s.defaultWriteObject();     
  295.       }     
  296. }    

你可能感兴趣的:(Throwable)