何为异常
异常是指程序在运行中由于外部问题导致的程序异常事件,产生的异常会中断程序运行。在Java中,异常也是一个对象,产生异常就是产生一个异常对象。异常不是错误。
Java内置异常类
异常的产生会有如下三个原因:
(1)Java内部错误发生异常,Java虚拟机产生的异常。
(2)编写程序代码中的错误所产生的异常。
(3)通过throw手动生成的异常。
我们把生成异常对象并交给运行系统的过程称为抛出异常。运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这个过程称为捕获异常。如果没有找到能处理该异常的对象,则运行系统终止。
在Java中Throwable位于异常类层次结构的顶层。Throwable类下面有两个分支Exception和Error,而Exception又可分为运行时异常和非运行时异常。
Error一般指与虚拟机相关的问题,如系统崩溃、虚拟机错误、内存不足等情况。遇到这样的情况,建议直接将程序终止。
RuntimeException包含NullPointerException、ArithmaticException等异常。
异常类型 | 说明 |
---|---|
Exception | 异常层次结构的根类 |
RuntimeException | 运行时异常,多数java.lang异常的根类 |
ArithmeticException | 算术异常,如以0作除数 |
ArrayIndexOutOfBoundException | 数组大小小于或大于实际的数组大小 |
NullPointerException | 尝试访问null对象成员,空指针异常 |
ClassNotFoundException | 不能加载所需的类 |
NumberFormatException | 数字转化格式异常,比如字符串到int转化无效 |
IOException | I/O异常的根类 |
FileNotFoundException | 找不到文件 |
EOFException | 文件结束 |
InterruptedException | 线程中断 |
IllegalArgumentException | 方法接收到非法参数 |
ClassCastException | 类型转换异常 |
异常处理机制
对于可查异常,必须捕获或者声明抛出。允许忽略不可查的RuntimeException和Error。
任何Java程序都可以通过throw语句抛出异常。从方法中抛出的任何异常都必须使用throws子句。捕获异常使用try…catch或者try…catch…finally语句。
(1)throws通常被用在声明方法时,用来指定方法可能抛出的异常,多个异常可用逗号隔开。throws可将异常抛给上一级。
(2)throw通常用在方法体中表示抛出一个异常对象。程序执行到throw语句时应立即停止。
finally用在异常处理的最后一个语句块,无论是否产生异常都要执行。但这不是绝对的,下列情况中finally不会触发:
(1)和finally相对应的try语句没有执行。
(2)finally执行前,程序或线程终止。(比如使用了return,System.exit)
对比:
(1)final:Java中的修饰符,表示类不能被继承,方法不能被重写,变量不能被修改。
(2)finalize:Object中的一个方法,GC删除对象之前会调用这个对象的这个方法。
如果同一个try块下的多个catch有父子关系,应该将子类异常放在前面。
自定义异常
(1)自定义一个编译器异常:自定义类并继承java.lang.Exception
(2)自定义一个运行时异常:自定义类并继承java.lang.RuntimeException
建议保留两种构造器:
(1)无参构造
(2)带给父类的message属性赋值的构造器
public class XXXException extends Exception|RuntimeException{
添加一个空参数的构造方法;
添加一个带异常信息的构造方法;
}
异常链
异常链指捕获一个异常,然后接着抛出另一个异常,并把原始信息保存下来。
try{
...
}catch(AException){
throw new CException("come from A");
}
try{
...
}catch(BException){
throw new CException("come from B");
}