1、第6章 异常处理Java异常体系结构Java异常处理机制Java异常的捕获、处理方法Java自定义异常的定义、抛出方法6.1.1 Java异常体系结构及处理机制异常的概念异常(Exception)又称为例外,是指在程序运行过程中发生的非正常事件,如用户数据输入错误、程序代码错误、文件找不到、对空对象进行操作等错误。异常事件的发生,中断了程序的正常执行,可能带来严重的后果和损失。Java异常体系结构 Java系统中提供了许多异常类,这些类又称为标准异常类,分布在Java.lang、Java.io、Java.util和J包中。所有的异常都是由一个称为Throwable类及其子类派生出来的,其层次结
2、构如图6.1所示。图图6.1 JavaJava异常体系结构异常体系结构 ThrowableThrowable类是Java语言中所有错误或异常的超类。Error与ExceptionError是Throwable的子类,是程序无法处理的错误。Exception类及其子类是Throwable的子类,是程序本身可以处理的异常,这种异常分运行时异常(RuntimeException)和非运行时异常两大类。运行时异常和非运行时异常运行时异常是在Java虚拟机正常运行期间抛出的异常的超类,Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,会编译通过,因此也称之为不检查异常(Unchecked
3、Exception)。运行时异常运行时异常说明说明ArithmeticException除数为除数为0引起的异常。引起的异常。IndexOutOfBoundsException由于数组下标越界或字符访问越界引起异常。由于数组下标越界或字符访问越界引起异常。ArrayStoreException数组存储空间不够引起的异常。数组存储空间不够引起的异常。IllegalArgumentException使用非法参数引起的异常。使用非法参数引起的异常。IllegalThreadStateException线程调用某个方法而所处状态不适当,引起异常。线程调用某个方法而所处状态不适当,引起异常。Number
4、FormatException字符的字符的UTF代码数据格式错误引起的异常。代码数据格式错误引起的异常。NegativeArraySizeException数组长度为负数产生的异常。数组长度为负数产生的异常。NullPionterException访问一个空数组中的元素或访问空对象中的成员引起的异常。访问一个空数组中的元素或访问空对象中的成员引起的异常。表表6.1 常见的常见的运行时异常运行时异常非运行时异常是RuntimeException以外的异常,也称为检查异常(Checked Exception),类型上都属于CheckedException类及其子类。从程序语法角度讲是必须进行处理的
5、异常,如果不处理,程序就不能编译通过,所以一般情况下编写程序时不自定义检查异常,常见非运行时异常如表6.2所示。非运行时异常非运行时异常说明说明ClassNotFoundException指定名字的类或接口未找到。指定名字的类或接口未找到。IllegalAccessException试图访问在另一个包的类中的方法,而该方法未声明为试图访问在另一个包的类中的方法,而该方法未声明为public。InstantiationException试图创建抽象类或接口的对象。试图创建抽象类或接口的对象。InterruptedException其他线程中断了当前线程时发生的异常。其他线程中断了当前线程时发生的
6、异常。IOException请求的请求的I/O操作无法完成。操作无法完成。EOFException在输入操作结束前遇到了文件尾。在输入操作结束前遇到了文件尾。FileNotFoundException未找到指定的文件或目录所引起的异常。未找到指定的文件或目录所引起的异常。InterruptedIOExceptionI/O:操作被中断。:操作被中断。UTFDataFormatExceptionUnicode文本格式的数据格式错误。文本格式的数据格式错误。SQLException数据库访问错误。数据库访问错误。ProtocolException网络协议的执行错误。网络协议的执行错误。SocketE
7、xception有关有关Socket的操作无法正常完成。的操作无法正常完成。UnknowHostException网络客户方指出的服务器地址有误。网络客户方指出的服务器地址有误。UnknownServiceException网络连接不能支持请求服务。网络连接不能支持请求服务。表表6.2 常见的常见的非运行时异常非运行时异常 Java异常分类Java异常类有两个来源,一是Java语言本身定义的一些基本异常类型,二是用户通过继承Exception类或者其子类自己定义的异常。Java异常的处理方法Java采用面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法生成代表该异常的
8、一个对象,并把它交给运行时系统,运行时系统寻找相应的代码来处理这一异常。6.1.2 异常的捕获和处理异常处理的基本结构在Java中,异常处理的基本结构是:try /可能出现特定异常的代码catch(异常类型异常的变量名)/异常处理代码finally /异常发生,方法返回之前,最终执行的代码 try、catch、finally三个语句块应注意的问题try、catch、finally三个语句块均不能单独使用,三者可以组成try.catch.finally、try.catch、try.finally三种结构,catch语句可以有一个或多个,finally语句最多只有一个。try、catch、fina
9、lly三个代码块中变量的作用域为代码块内部,分别独立而不能相互访问。如果要在三个块中都可以访问,则需要将变量定义到这些代码块的外面。在有多个catch块的情况下,如果处理的异常类型之间具有继承关系,应该首先捕获子类异常,再捕获父类异常例如:例如:class TeacherString name,number;int age,num;Teacher(String name,int age)this.name=name;this.age=age;void setNumber(String number)try/try/异常处理异常处理num=Integer.parseInt(number);cat
10、ch(NumberFormatException e)System.out.println(System.out.println(工号格式错误!工号格式错误!);int getNumber()return num;public static void main(String args)Teacher t1=new Teacher(Teacher t1=new Teacher(黎明黎明,28);Teacher t2=new Teacher(Teacher t2=new Teacher(张力张力,30);t1.setNumber(2a001);t2.setNumber(22001);System.
11、out.println(System.out.println(工号:工号:+t2.getNumber();6.1.3 自定义异常自定义异常类可以继承Throwable类或者Exception,而不要继承Error类,自定义异常类之间也可以有继承关系。自定义异常必须使用throws声明方法可能抛出的自定义异常,并用throw语句在适当的时候抛出自定义异常。例如:例如:class MyException extends Exception/class MyException extends Exception/定义自定义异常定义自定义异常MyException()/MyException()/定义
12、构造方法定义构造方法super();MyException(String s)super(s);class TeacherString name,number;int age;Teacher(String name,int age)this.name=name;this.age=age;void setNumber(String number)throws MyExceptionif(number.equals(2a001)throw new MyException(throw new MyException(自定义异常自定义异常);elsethis.number=number;String
13、getNumber()return number;public static void main(String args)Teacher t1=new Teacher(Teacher t1=new Teacher(黎明黎明,28);Teacher t2=new Teacher(Teacher t2=new Teacher(张力张力,30);tryt2.setNumber(22001);t1.setNumber(2a001);catch(MyException e)System.out.println(System.out.println(出现自定义异常!出现自定义异常!);finallySys
14、tem.out.println(System.out.println(工号:工号:+t2.getNumber();6.1.4 抛出异常使用throw关键字抛出异常throw关键字是用于方法体内部,用来抛出一个Throwable类型的异常。throw语句的格式为:throw 异常类对象名;使用throws关键字声明抛出异常当方法的调用者不能处理该异常的时候,应该将它向上传递,由调用它的方法来处理异常。throws语句的格式为:方法修饰符 返回值的类型成员方法名(形式参数表)throws 异常表/方法声明/方法体例如:例如:class TeacherString name,number;int a
15、ge,num;Teacher(String name,int age)this.name=name;this.age=age;void setNumber(String number)throws NumberFormatException/声明要抛出的异常声明要抛出的异常if(number.equals(2a001)/抛出异常抛出异常throw new NumberFormatException();elsethis.number=number;String getNumber()return number;public static void main(String args)Teache
16、r t1=new Teacher(Teacher t1=new Teacher(黎明黎明,28);Teacher t2=new Teacher(Teacher t2=new Teacher(张力张力,30);t1.setNumber(2a001);/满足异常条件,系统会抛出异常满足异常条件,系统会抛出异常t2.setNumber(22001);System.out.println(t2.getNumber();6.1.5 Throwable类中的常用方法方法方法说明说明getCause()返回抛出异常的原因。如果返回抛出异常的原因。如果 cause 不存在或未知,则返回不存在或未知,则返回 null。getMessage()返回异常的消息信息。返回异常的消息信息。printStackTrace()功能是完成一个打印操作,在当前的标准输出上打印输出当前异常对象的堆栈使用轨迹,功能是完成一个打印操作,在当前的标准输出上打印输出当前异常对象的堆栈使用轨迹,也即程序先后调用执行了哪些对象或类的哪些方法,使得运行过程中产生了这个异常对也即程序先后调用执行了哪些对象或类的哪些方法,使得运行过程中产