重点:
- try-catch块
- try-catch-finally块
- 多重catch块
难点:
- throws和throw
- 自定义异常
1.1异常概述
1.1.1认识异常
异常就是在程序的运行过程中所发生的不正常事件,如所需文件找不到、网络连接不通或中断、算术运算出错(如被零除)、数
组下标越界、装载一个不存在的类、对null对象操作、类型转换异常等。异常会中断正在运行的程序。
可以通过增加if-else语句对各种情异常情况进行判断处理,但有很多缺点,不推荐使用。
1.1.2Java异常体系结构
Java中的异常有很多类型。异常在Java中被封装成了各种异常类,Java的异常体系如下:
Object
-----------------------------
Throwable
-----------------------------
Error Exception
------------------------------
AWTError RuntimeException、 ArithmeticException
ThreadDeath NullpointerException、 NumberFormatException
SQLException、 ClassNotFoundException
所有异常类型都是Throwable类的子类,它派生两个子类:Error类和Exception类。
- Error类:表示仅靠程序本身无法恢复的严重错误,如内存溢出、动态连接失败等。
- Exception类:由Java应用程序抛出和处理的非常严重错误,如所需文件找不到、网络连接不上或中断、算术运算出错等。
常见的异常类型
Exception | 异常层次结构的根类 |
ArithmeticException | 算术错误情形,如以零作为除数 |
ArrayIndexOutOfBoundsException | 数组下标越界 |
NullPointerException | 尝试访问null对象成员 |
ClassNotFoundException | 不能加载所需的类 |
InputMismatchException | 欲得到的数据类型与实际输入的类型不匹配 |
IllegalArgumentException | 方法接收到非法参数 |
ClassCastException | 对象强制类型转换出错 |
NumberFormatException | 数字格式转换异常,如把"abc"转换成数字 |
1.2Java异常处理机制
1.2.1异常处理
Java的异常处理是通过5个关键字来实现的,
即try、catch、finally、throw和throws.
1.2.2使用try-catch处理异常
Java中提供了try-catch结构进行异常捕捉和处理,把可能出现异常的代码放入try语句块中,并使用catch语句块捕捉异常。
- 如果try语句块中所有语句正常执行完毕,不会发生异常,那么catch语句块中的所有语句都将会被忽略。
- 如果try语句块在执行过程中发生异常,并且这个异常与catch语句块中声明的异常类型相匹配,那么在try语句块中其余剩下的代码都将被忽略,而相应的catch语句块将会被执行。
- 如果try语句块在执行过程中碰到异常,而抛出的异常在catch语句块中没有被声明,那么方法立刻退出。
1.2.3使用try-catch-finally处理异常
如果希望不管是否发生异常,都执行输出的语句,就需要在try-catch语句块后面加入finally语句块,把要执行输出的语句
放入finally语句块中。无论是否发生异常,finally语句块中的代码总能被执行。
1.2.4使用多重catch处理异常
一个try语句块后面跟多个catch语句块,分别处理不同的异常。但排列顺序必须是从子类到父类,最后一个一般都是
Exception类。
1.2.5使用throws声明抛出异常
如果在一个方法体中抛出了异常,希望调用者能够去及时地捕捉异常,Java语言中通过关键字throws声明某个方法可能抛出的
各种异常以通知调用者。可以声明多个异常,之间由逗号隔开。
例如:
在divide()方法的参数列表后通过throws声明了异常,然后再main()方法中调用该方法,此时main()方法就知道
divide()方法抛出了异常,可以采用两种方式进行处理:
- 通过try-catch捕捉并处理异常。
- 通过throws继续声明异常。如果调用者不知道如何处理异常,可以继续通过throws声明异常,让上一级调用者处理异常。main()方法声明的异常将由Java虚拟机来处理。
1.2.6使用throw抛出异常
除了系统自动抛出异常外,在编程过程中,有些问题时系统无法自动发现并解决的,如年龄不在正常范围内,性别输入不是"男"
或"女"等,此时需要程序员而不是系统来自行抛出异常,把问题交给调用者去解决。
例:
public void setSex(String sex) throws Exception{
//省略代码
}
throw和throws的区别:
- 作用不同:throw用于程序员自行产生并抛出异常,throws用于声明该方法内抛出了异常。
- 使用的位置不同:throw位于方法体内部,可以作为单独语句使用;throws必须跟在方法参数列表的后面,不能单独使用。
- 内容不同:throw抛出一个异常对象,且只能是一个;throws后面跟异常类,且可以跟多个异常类。
1.2.7自定义异常
当JDK中的异常类型不能满足程序的需要时,可以自定义异常类。步骤:
- 定义异常类,并继承Exception或者RuntimeException。
- 编写异常类的构造方法,并继承父类的实现。、
常见的构造方法有4种形式。//构造方法1public MyException(){super();}//构造方法2public MyException(String message){super(message);}//构造方法3public MyException(String message,Throwable cause){super(message,cause);}//构造方法4public MyException(Throwable cause){super(cause);}
- 实例化自定义异常对象,并在程序中使用throw抛出。
1.2.8异常链
A方法调用B方法时,B方法却抛出了异常。那么A方法是继续抛出原有的异常还是抛出一个新的异常呢?若抛出原有的异常将是
很糟糕的设计方法。因为A方法与B方法进行了关联,不便于代码的修改和扩展。若抛出新异常,虽然解决了A方法和B方法的关
联问题,但是原有的异常信息却会丢失。JDK1.4以后出现了异常链,异常链的出现真是解决这个问题。它虽然创建了新的异常,
却保留了原有的异常信息。
总结
- 异常就是在程序的运行过程中所发生的不正常事件。
- Java的异常处理是通过5个关键字来实现的,即try、catch、finally、throw和throws。
- 即使在try语句块、catch语句块中存在return语句,finally语句块中的语句也会执行。finally语句块中语句不执行的唯一情况:在异常处理代码中执行System.exit(1)。
- 可以在一个try语句块后面跟多个catch语句块,分别处理不同的异常。但排列顺序必须是从特殊到一般,最后一个一般都是Exception类。
- java语言中通过关键字throws声明某个方法可能抛出的各种异常以通知调用者。
- 在java语言中,可以使用throw关键字自行抛出异常。
- 自定义异常类,一般需要继承Excepion或者RuntimeException。