JAVA编程——Throwable常见异常及源码详解

<span style="font-family:Microsoft YaHei;font-size:14px;"><span lang="EN-US">Throwable</span>是<span lang="EN-US">java.lang</span>包中一个专门用来处理异常的类。它有两个子类,即<span lang="EN-US">Error </span>和<span lang="EN-US">Exception</span>,它们分别用来处理两组异常。</span><span style="font-family:Microsoft YaHei;font-size:14px;">
</span>
<span style="font-family:Microsoft YaHei;font-size:12px;"><span lang="EN-US">Error</span>用来处理程序运行环境方面的异常,这类异常主要是和硬件有关的,而不是由程序本身抛出的。<span lang="EN-US"> 
Exception</span>是<span lang="EN-US">Throwable</span>的一个主要子类。                                                                                                                                                                           <span style="white-space:pre">	</span></span><span style="font-family:Microsoft YaHei;font-size:12px;"><span lang="EN-US">Exception</span>下面还有子类,其中一部分子类分别对应于<span lang="EN-US">Java</span>程序运行时常常遇到的各种异常的处理,其中包括隐式异常。<span>							</span><span lang="EN-US">Exception </span>子类下面的另一部分子类对应于<span lang="EN-US">Java</span>程序中的非运行时异常的处理(在下图中将它们直接属于<span lang="EN-US">Exception</span>了),这些异常也称为显式异常。它们都<span style="white-space:pre">	</span>是在程序中用语句抛出、并且也是用语句进行捕获的。</span><span lang="EN-US" style="font-family: Arial, Helvetica, sans-serif;"><span style="font-family:Microsoft YaHei;font-size:12px;"> </span></span>
<span lang="EN-US"><span style="font-family:Microsoft YaHei;"><span style="font-size:12px;">
</span></span><span style="font-family:Microsoft YaHei;font-size:12px;">    </span></span><span style="font-family:Microsoft YaHei;font-size:12px;">一些主要子类对应的异常处理功能简要说明如下:<span lang="EN-US"> 
    ArithmeticException——</span>由于除数为0引起的异常;<span lang="EN-US"> 
    ArrayStoreException——</span>由于数组存储空间不够引起的异常;<span lang="EN-US"> 
    ClassCastException—</span>一当把一个对象归为某个类,但实际上此对象并不是由这个类 创建的,也不是其子类创建的,则会引起异常;<span lang="EN-US"> 
    IllegalMonitorStateException——</span>监控器状态出错引起的异常;<span lang="EN-US"> 
    NegativeArraySizeException—</span>一数组长度是负数,则产生异常;<span lang="EN-US"> 
    NullPointerException—</span>一程序试图访问一个空的数组中的元素或访问空的对象中的 方法或变量时产生异常;<span lang="EN-US"> 
    OutofMemoryException——</span>用<span lang="EN-US">new</span>语句创建对象时,如系统无法为其分配内存空间则产生异常;<span lang="EN-US"> 
    SecurityException——</span>由于访问了不应访问的指针,使安全性出问题而引起异常;<span lang="EN-US"> 
    IndexOutOfBoundsExcention——</span>由于数组下标越界或字符串访问越界引起异常;<span lang="EN-US"> 
    IOException——</span>由于文件未找到、未打开或者<span lang="EN-US">I/O</span>操作不能进行而引起异常;<span lang="EN-US"> 
    ClassNotFoundException——</span>未找到指定名字的类或接口引起异常;<span lang="EN-US"> 
    CloneNotSupportedException——</span>一程序中的一个对象引用<span lang="EN-US">Object</span>类的<span lang="EN-US">clone</span>方法,但 此对象并没有连接<span lang="EN-US">Cloneable</span>接口,从而引起异常;<span lang="EN-US"> 
    InterruptedException—</span>一当一个线程处于等待状态时,另一个线程中断此线程,从 而引起异常,有关线程的内容,将在下一章讲述;<span lang="EN-US"> 
    NoSuchMethodException</span>一所调用的方法未找到,引起异常;<span lang="EN-US"> 
    Illega1AccessExcePtion—</span>一试图访问一个非<span lang="EN-US">public</span>方法;<span lang="EN-US"> 
    StringIndexOutOfBoundsException——</span>访问字符串序号越界,引起异常;<span lang="EN-US"> 
    ArrayIdexOutOfBoundsException—</span>一访问数组元素下标越界,引起异常;<span lang="EN-US"> 
    NumberFormatException——</span>字符的<span lang="EN-US">UTF</span>代码数据格式有错引起异常;<span lang="EN-US"> 
    IllegalThreadException—</span>一线程调用某个方法而所处状态不适当,引起异常;<span lang="EN-US"> 
    FileNotFoundException——</span>未找到指定文件引起异常;<span lang="EN-US"> 
    EOFException——</span>未完成输入操作即遇文件结束引起异常。</span><span style="font-family:Microsoft YaHei;font-size:14px;">
</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">源码解析:</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">	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();  
	      }  
	}  
</span>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值