Throwable源码详解

packagejava.lang; 

       importjava.io.*; 

       /**

       * 

       *Throwable是所有Error和Exceptiong的父类

       *注意它有四个构造函数:

       *Throwable()

       *Throwable(String message)

       *Throwable(Throwable cause)

       *Throwable(String message, Throwable cause)

       * 

扫描二维码关注公众号,回复: 10890024 查看本文章

       */ 

       publicclass Throwable implements Serializable { 

             private static final longserialVersionUID = -3042686055658047285L; 

        

             /**

              * Native code saves some indication ofthe 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 ThrowableinitCause(Throwable cause) {  

                //如果不是未初始化状态则抛出异常 

                 if (this.cause != this) 

                     throw newIllegalStateException("Can't overwrite cause"); 

               //要设置的起因对象与自身相等则抛出异常 

                 if (cause == this) 

                     throw new IllegalArgumentException("Self-causationnot 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(PrintStreams) { 

                 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 voidprintStackTraceAsCause(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(PrintWriters) {  

                 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 voidprintStackTraceAsCause(PrintWriter s, 

                                                StackTraceElement[] causedTrace) 

             { 

                 // assert Thread.holdsLock(s);        

                 // Compute number of frames in commonbetween 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 ThrowablefillInStackTrace();         

             /**

              * 返回当前的异常轨迹的拷贝

              */ 

             public StackTraceElement[]getStackTrace() { 

                 return (StackTraceElement[])getOurStackTrace().clone(); 

             }                 

             /**

              * 获取当前的异常轨迹

               */ 

     private synchronized StackTraceElement[] getOurStackTrace() { 

                //如果第一次调用此方法则初始化异常轨迹数组 

                 if (stackTrace == null) { 

                   //获得异常轨迹深度 

                     int depth =getStackTraceDepth(); 

                   //创建新的异常轨迹数组,并填充它 

                     stackTrace = newStackTraceElement[depth];                     

                   for (int i=0; i < depth;i++) 

                       stackTrace[i] =getStackTraceElement(i);//获取指定位标的异常轨迹 

                 }                 

                 return stackTrace; 

             }   

             /**

              * 设置异常轨迹

              */ 

             public voidsetStackTrace(StackTraceElement[] stackTrace) { 

                //拷贝设置参数 

                 StackTraceElement[] defensiveCopy= 

                     (StackTraceElement[])stackTrace.clone();                 

                //如果设置参数有空元素则抛出异常 

                 for (int i = 0; i <defensiveCopy.length; i++) 

                     if (defensiveCopy[i] ==null) 

                         throw newNullPointerException("stackTrace[" + i + "]");      

                //设置当前对象的异常轨迹 

                 this.stackTrace = defensiveCopy; 

             } 

             /**

              * 异常轨迹的深度,0表示无法获得

              */ 

             private native intgetStackTraceDepth();        

             /**

              * 获取指定位标的异常轨迹

              */ 

             private native StackTraceElementgetStackTraceElement(int index);     

             private synchronized voidwriteObject(java.io.ObjectOutputStream s) 

                 throws IOException 

             { 

                 getOurStackTrace(); 

                 s.defaultWriteObject(); 

             } 

       } 

发布了21 篇原创文章 · 获赞 21 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/a768818702/article/details/104780345