(一)异常的简介
异常的顶级父类是Throwable。Throwable分为两大类:错误 error,异常 exception
error:表示程序中出现了非常严重的问题,不修改源代码不能继续执行。
exception:表示程序中出现了不太严重的问题,处理好异常后代码可以继续向下执行。
异常信息产生的过程:出现异常后,会创建异常对象,如果没有方法处理异常,异常会一直向上抛(谁调用出现异常的方法就会抛给谁)
一直会抛到jvm,jvm会停止程序的运行,并且抛出异常信息在控制台上。
(二)运行时异常与编译时异常
异常分为两大类:
运行时异常:包含RuntimeException和它的子类。在编译期间无需处理就可以编译通过。运行时才抛出异常。
编译期异常:除了RuntimeException和它的子类的其他异常。编译期异常在编译期间必须处理,否则编译不通过。
(三)try..catch ,finally关键字
异常的处理方式:
1、在方法后面 throws 异常类
2、try{
可能出现异常的代码
}catch(异常类 变量名){
可以捕获到出现的对应的异常;
打印栈轨迹;
}
【注意点1】
当捕获异常成功后,try里面的内容只执行到异常的语句。执行完之后,如果没有try..catch中没有return语句。程序依然会继续向下执行。
【注意点2】
关于finally
finally代码块中的代码能够保证一定会被执行。
当try中有return语句时,程序会执行一个“挂起”操作。在返回之前,去执行finally里面的内容,如果finally里面有return语句,则直接返回。如果没有,则执行finally里面的内容之后,在将挂起的内容返回。
注意:当挂起的内容为基本数据类型的时候,如果finally中使用到该数据的时候,则会将该数据值复制一份给finally中内容的操作。但返回的内容,仍然是挂起时的内容,不会因为finally的操作,而发生改变。
当挂起的内容为引用数据类型的时候,如果finally中使用到该数据的时候,则会将该数据值的地址复制一份给finally中内容的操作。如果在finally中通过该地址,修改了引用类型的值。则返回的内容会为之改变。
挂起的操作有点像方法的值传递与引用传递。
【注意点3】
重载、重写与异常的关系
重载本质上是一个编译时多态,异常对于重载没有影响
重写本质上是一个运行时多态,运行时异常对于重写没有影响。但编译时异常子类的方法的异常必须小于或者等于父类异常的范围。
【注意点4】
throw是自己抛出异常,自己丢出异常。throw new IOException().....
throws是向上抛出异常,交给调用它的方法处理,或继续往上抛。
【注意点5】
throw 与 return 不能共存在一处代码块中。
同样当finally有返回值的时候,finally外面就不要使用return语句了。否则会报错。
(四)异常的分组捕获
如果异常的处理代码完全不同,那么只能使用catch捕获不同的异常,一个个处理。
如果异常的处理代码完全相同,那么可以使用所有可能出现的异常的父类来捕获,在一个catch中统一处理。
在JDK1.7特性:如果异常的处理代码有部分相同,那么可以使用分组捕获。
分组捕获格式:catch(异常类1 | 异常类2 | 异常类3 … 变量名)
【注意】:一级一级捕获异常,按照子类和父类的顺序放置,子类在上,父类在下。
(五)自定义异常
- 先自定义一个类,继承异常。让自定义类成为异常类的一员
- 提供无参和有参的构造方法
- 有参构造方法中直接调用父类的有参构造方法。
public class MyException extends Exception{
public MyException() {
}
public MyException(String message) {
super(message);
}
}
这样就可以了。
注意:如果没有继承RuntimeException,它就不是运行时异常。就是编译时异常。当使用throw抛出的异常的时候,也要在方法上throws抛出异常名称。