Java异常机制Throwable

Java中异常的概念以及处理异常

在Java程序运行期间出现了一个错误,这个错误可能是由于文件包含了错误信息,或者是由于网络连接出现问题,也可以是因为使用了无效的数组下标,或者是试图使用一个没有被赋值的对象引用而造成的,我们称这样的错误为异常。在出现异常时用户期望程序能够采用一些理性的行为。如果由于出现错误而使得程序操作没有完成,这时程序应该:
  • 返回到一种安全状态,并能够让用户执行一些其他命令
  • 允许用户保存所有操作的结果,并以适当的方法终止程序,

异常类的结构体系

                         
从上图中我们可以知道,所有的异常类都是由Throwable继承下来的,但在下一层立即分为两个分支:Error和Exception。
一、Error
1、Error类层次描述了Java运行时系统的内部错误和资源耗尽错误。对于这类错误是无法难通过程序来解决的,所以程序不应该抛出这种类型的对象。如果出现了这样的内部错误,除了通知给用户,并尽力使程序安全地终止。当然这类情况是很少出现的
二、Exception
在设计Java程序时,Exception是我们需要重点关注的错误,在Java程序中Exception又可以分为两类:Runtime Exception、其它异常如:IOException。
1、派生于Runtime Exception 的异常主要包含以下几种情况 
  • 错误的类型转换
  • 数组访问越界
  • 访问空指针
2、不是派生于Runtime Exception的异常包含
  • 试图在文件尾部读取数据
  • 试图打开一个错误格式的URL
  • 试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在
这里总结一条:如果是出现RuntimeException,那么就一定是自己的问题。
三、运行时异常和检查性异常
1、在Java语言中将派生于Error或RuntimeException类的所有异常称为运行时异常,这类异常我们可以不处理,当出现这个的异常时,总是由虚拟机接管,比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。运行时异常我们常见的有 ClassCastException(类转换异常) IndexOutOfBoundsException(数组越界) NullPointerException(空指针) ArrayStoreException(数据存储异常,操作数组时类型不一致) 还有IO操作的BufferOverflowException异常 ;
2、除了运行时异常,其它的异常都被称为 检查性异常 我们经常遇到的IO异常及sql异常就属于检查式异常。对于这种异常,Java编译器要求我们必须对出现的这些异常进行catch 所以 面对这种异常不管我们是否愿意,只能自己去写一堆catch来捕捉这些异常。常见的查检性异常有:FileNotFoundException 文件不存在异常、SQLException SQL异常等。

抛出和捕捉异常的方法

一、使用throws抛出异常
1、使用throws抛出异常的情况:
  • 调用一个抛出已检查异常的方法,如:FileInputStream构造器
  • 程序运行过程中发现错误,并且利用throw语句抛出一个已检查异常
  • 程序出现错误,如:a[-1]=0会抛出一个ArrayIndexOutOfBoundsException这样的未检查异常
  • Java虚拟机和运行时库出现的内部异常。
[java]  view plain  copy
  1. public class A**Exception   {     
  2.               private String id;     
  3.               public void setID(String id)  throws IllegalException{  
  4.                           if(id.length() == 7) {    
  5.                                  this.id = id;     
  6.                          }else{     
  7.                                throw new IllegalArgumentException("参数长度不是7位");     
  8.                         }     
  9.              }     
  10. }    

上面的代码,表示就抛出了一个IllegalArgumentException类型的异常,如果在一个方法体中抛出了异常,那么就希望调用者能够去捕获异常,在Java语言中可以通过throws来声明某个方法可能会抛出的异常,这样就可以让调用者明白该方法可能会出现什么异常,要及时去捕获。

二、使用try{....}catch(){....}finally{....}捕捉异常
[java]  view plain  copy
  1. try{  
  2.        //执行的代码,其中可能有异常。一旦发现异常,则立即跳到catch执行。否则不会执行catch里面的内容    
  3.     }catch (Exception e) {  
  4.        //除非try里面执行代码发生了异常,否则这里的代码不会执行   
  5.     }finally{  
  6.       //不管什么情况都会执行,包括try catch 里面用了return ,可以理解为只要执行了try或者catch,就一定会执行 finally   
  7.     }  
关于try...catch...finally方法的说明:
[java]  view plain  copy
  1. package com.exception;  
  2. public class TryCatchUse {  
  3.     public static void main(String[] args) {  
  4.        try{  
  5.             System.out.println("try statement...");  
  6.             //Integer.valueOf("2");//没有异常    
  7.             Integer.valueOf("admin");//有异常  
  8.          }catch (NumberFormatException e) {  
  9.             System.out.println("catch statement...");  
  10.             e.printStackTrace();//打印出异常信息  
  11.          }finally{  
  12.             System.out.println("finally statement...");  
  13.          }  
  14.          System.out.println("after finally statement...");  
  15.     }  
  16. }  
a、如果try中没有出现异常,那么catch中的代码不会执行。执行完try中代码后直接执行finally中代码。
b、如果try中出现异常,就会停止运行try中的代码,直接跳到catch中运行其中代码,catch中代码运行完后,再运行finally中的代码。
c、如果没有出现异常,但是try中存在return,或者是出现异常,但是catch中存在异常,这时finally后的代码都不会执行。
d、finally并不是捕获异常的必须部分,当我们需要关闭一些由于异常而无法关闭的资源时需要用到finally。
下面是一组结果图:
a、没有异常的try...catch...finally...,且try中或catch中都不含有return

                   

b、有异常,但是catch中有return 的try...catch...finally...

                    
c、没有异常,但是try中有return的try...catch...finally...

                   

d、有异常,但是catch中没的return的情况:

                 

总结:finally不是必须的,但是只要有finally,不管有没有异常finally中的代码都必须要执行,其次,如果try中和catch中都不主动跳出程序即都不包含return,那么不管会不会出现异常,try...catch...finally 块后面的代码都会正常执行,最后,一旦try中的某一行出现异常,就会直接跳到catch中,try中位于这一行后面的代码都不会执行。 
三、自定义异常类
     在程序中,可能会遇到任何标准异常类都没有能够充分地描述清楚的问题。在这种情况下,需要创建自己的异常类,这个自己定义的异常类一般都是继承Exception或者Exception的子类。通常情况下,自己定义的异常类应该有两个构造器,一个是默认的构造器,另一个是带有详细描述信息的构造器。下面就是定义自己的异常类的两种方式:
[java]  view plain  copy
  1. package com.exception;  
  2. /*当标准的异常类不能充分的描述清楚问题时,这时需要自定义异常类。 
  3.  * 自定义的异常类有两种方式 
  4.  * 一是继承Exception这个异常主类,或者是继承Exception这个主类的子类 
  5.  * 二是继承Throwable类 
  6.  * */  
  7. public class MyException extends Exception{  
  8.     private static final long serialVersionUID = 1L;  
  9.     public MyException(){  
  10.         super();  
  11.     }  
  12.     public MyException(String msg){  
  13.         super(msg);  
  14.     }  
  15.     public MyException(String msg,Throwable cause){  
  16.         super(msg,cause);  
  17.     }  
  18.     public MyException(Throwable cause){  
  19.         super(cause);  
  20.     }  
  21. }  
  22. //自定义异常类的第二种方式  
  23. class MyException_another extends Throwable{  
  24.     private static final long serialVersionUID = 1L;  
  25.     public MyException_another() {  
  26.         super();  
  27.     }  
  28.     public MyException_another(String msg) {  
  29.         super(msg);  
  30.     }  
  31.     public MyException_another(String msg, Throwable cause) {  
  32.         super(msg, cause);  
  33.     }  
  34.     public MyException_another(Throwable cause) {  
  35.         super(cause);  
  36.     }  
  37.       
  38. }  

猜你喜欢

转载自blog.csdn.net/make__it/article/details/78729332