1.Java异常处理的抓抛模型
过程一:"抛":程序在正常执行的过程中,一旦出现异常,就会在异常代码块处生成一个对应异常类的异常对象,并将此对象抛出,抛出对象后,其后的代码就不会再执行。
1.1关于异常对象的产生:
1.1.1:① 系统自动生成的异常对象
1.1.2:② 手动生成的异常对象,并抛出(throw new 异常对象)
过程2:"抓":可以理解为异常的处理方式:① try - catch - finally ② throw 抓补的异常对象名
2.异常处理方式一:try - catch - finally
2.1 使用说明:
1. finally是可选的,可写可不写,不会影响 try - catch
2. 使用try将可能出现异常的代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此 对象的类型,去catch中进行匹配,
3. 一旦try中的异常对象匹配到某一个catch时,就进入到catch中进行异常的处理,一旦处理完成,就跳出当前try - catch的结构(如果在没写finally的情况,继续执行其后的代码)
4. catch中的异常类型,如果没有子父类的关系,那么声明前后无所谓。
catch中的异常对象如果满足子父类的关系,则要求子类声明在父类的上面,否则,报错。
如果父类在子类的上面,如果要特定处理子类的异常,那么就永远处理不到,因为父类会包含子类的方法,所以只 能先处理子类,再处理父类,这样就不会造成checkedException
5. 常用异常类处理的方式:String getmessage() --- printStackTrace()
6. 在try结构中声明的变量,出了try结构,就不能再被调用
int b;
try{
int a = 0; // 这个是局部变量,但如果是另一种写法就可以调用了
b = 0; // 可以在try结构外部声明它,但如果是在结构内声明的,就不行了
}
7. try - catch - finally 可以嵌套
总结:如何看待编译时异常和运行时异常?
运行时异常,可以考虑不去处理,但编译时异常必须要处理,不然,就无法运行
2.2 finally的再说明
1.finally是可选的
2.finally中是一定会被执行的代码,即使catch中出现异常了,它也会先执行,再返回异常,try中的return语句也是 同理。
3.像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动回收的,我们需要自己手动的进行资源的释 放。此时的资源释放,需要声明在finally中不然,在try中或在catch中出现意外就会导致资源无法回收。
3.异常处理方式二:throws 异常类型
throws + 异常类型写在方法的声明处,指明此方法执行时,可能会抛出的异常类型。一旦方法体执行时,出现异常,仍会在此处生成一个异常类型的对象,此对象满足throws的情况,就会被抛出,异常代码后续的代码就不会被执行。
4.对比两种处理方式
try - catch - finally 真正的将异常处理掉了。
throws的方式只是将异常抛给了方法的调用者。 并没有真正的将异常处理掉。
5.体会开发中应该如何选择两种处理方式
5.1 如果父类中被重写的方法没throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果子类中重写 的方法异常,只能使用try - catch - finally 方式进行处理。
原因是:子类不能抛出比父类更多的异常,或者说子类重写父类的方法就得和父类一模一样
5.2 执行方法的a中,先后又调用了几个另外的方法,这几个方法是递进关系执行的。我们建议这几个方法使用 throws+异常类型的方式进行处理,而执行的方法a可以考虑使用try - catch - finally的方式进行处理。
补充:
方法重写的规则之一:
子类重写的方法抛出的异常类型不大于父类被重写的异常类型