一、异常体系结构
上图为Java的异常类体系。Throwable是所有异常类的基类。它有两个子类,Error和Exception。
Error:该类异常是Java虚拟机无法解决的问题,发生Error时没有针对性的代码进行处理的一类异常。
Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理的一类异常。
其中,Exception又可划分为编译时异常和运行时异常。
编译时异常:(1) 程序在编译时发生的异常(javac 源文件名.java)
(2) 编译时异常必须处理,否则程序不能执行。
如:FileNotFoundException : 文件找不到异常
运行时异常:程序在运行时发生的异常(java 字节码文件名)。
如: NullPointerException : 空指针异常
ArrayIndexOutOfBounds : 数组下角标越界
注:运行时异常一般不强制要求程序员进行处理
二、抓抛模型
(1)抛 (发生异常: 当程序在正常的执行过程中,如果一旦执行到某行代码时发生异常。那么系统(JVM将会根据异常的类型)创建对应异常类型的对象并抛出,抛出给代码的执行者,同时终止程序的运行。 抛异常的方式: ①系统向外抛 ②手动向外抛 throw(2) 抓(处理异常)的方式: ① try-catch-finally ② throws
三、异常的处理
1.try-catch-finally
1.格式 :
try{
可能会发生异常的代码
}catch(异常类型1 变量名){
处理异常的代码
}catch(异常类型2 变量名){
处理异常的代码
}
......
finally{
一定会执行的代码
}
2.说明:
1.在执行try中的代码时一旦发生异常,系统会根据对应的异常类型创建对象并抛出。然后会根据catch后面的异常类型进行匹配,
一旦匹配成功则执行相应的代码。执行完毕后如果有finally那么继续执行finally中的代码,然后跳出try-catch结构继续向下执行。
如果没有和catch后面的异常类型匹配成功,则终止程序的执行,如果有finally则继续执行finally中的代码。
2.finally可以省略,但是如果写了finally,则其中的代码一定会执行。
3.catch可以多个,catch后面的异常类型如果存在子父类关系那么子类在上父类在下。
如果不存在子父类关系那么谁上谁下都可以
4.可以的结构方式 : try-finally try-catch try-catch-finally
5.处理异常的方式 :
getMessage() - 异常信息 (使用自定义异常时用的比较多)
printStackTrace() - 异常的详细信息
3 finally的再说明
1.就算catch中再次发生异常,finally也一定会执行
2.就算在try和catch中执行了return那么finally中的代码也一定会执行。
3.如果try或catch语句中有return语句,则return语句在finally语句执行结束后才能执行,但finally语句并不改变返回值;如果finally语句中也有return语句,则try和catch内的return会丢失,实际返回的时finally中的返回值。
4.finally语句中的return不仅会覆盖try和catch内的返回值,还会掩盖try和catch内的异常,就像异常没有发生一样。
2.throws
1.格式:
throws 异常类型1, 异常类型2.......
2.throws和try-catch的区别?
throws :本身没真正的处理掉异常而是把异常向上抛,抛给方法的调用者去处理。
try-catch-finally :真正的处理掉了异常
3.什么情况下不能使用throws?
(1) 需要真正处理异常时
(2) 父类被重写的方法没有throws,子类重写的方法也不能throws
4.什么情况下必须使用throws?
当我们需要调用多个方法进行数据的传递,如果是因为数据的原因造成的异常,那么中间任何方法都不能去处理,只能由方法的调用者(写数据的那人进行处理)。
四、手动抛出异常throw
作用 :手动向外抛异常
格式 :throw 异常类的对象
[面试题]throw和throws的区别?
throw : 制造异常
throws : 处理异常
五、自定义异常类
除了Java API中定义的异常类,也可以自己定义异常类,一般是继承Exception或者它的某个子类。如果父类是RuntimeException或它的某个子类,则自定义异常一般不强制要求程序员进行处理。
代码
public class MyException extends RuntimeException{
/**
* serialVersionUID也可以不写系统默认会添加一个,但是建议显示提供一个
*/
private static final long serialVersionUID = -7736287090372348682L;
public MyException(){
}
public MyException(String message){
super(message);
}
}