Java.lang.throwable源代码

Java代码   收藏代码
  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. }  
  297. 转载于http://riddickbryant.iteye.com/blog/444185
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值