黑马程序员技术交流社区

标题: Throwable源码详解 [打印本页]

作者: zzm0717    时间: 2016-5-9 23:05
标题: 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();  
              }  
        }  
作者: wan1137856139    时间: 2016-5-9 23:12
迭代器原理
        * 迭代器原理:迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可
* B:迭代器源码解析
        * 1,在eclipse中ctrl + shift + t找到ArrayList类
        * 2,ctrl+o查找iterator()方法
        * 3,查看返回值类型是new Itr(),说明Itr这个类实现Iterator接口
        * 4,查找Itr这个内部类,发现重写了Iterator中的所有抽象方法
作者: zzm0717    时间: 2016-5-10 22:14
啥玩意?
作者: 溪溪笑    时间: 2016-5-10 22:25
看一看。。。。。。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2