文章说明:黑色字体-已知,蓝色字体-所见即所得,红色字体-还需要再找资料弄明白的,黄色背景-提炼关键信息
参考资料:很多参考资料,段落下有原文链接到原作者
关于执行顺序(前言)
1、try+catch
2、try+catch+finally
3、try+finally
try有异常执行finally。finally后面的代码不会执行。因为没有处理异常,所以遇到异常后,执行完finally后,方法就已抛出异常的方式退出了。
(假设方法需要返回值)
无异常无finally,直接return。
有 finally,try 里的 return 不会立即执行,先执行 finally ,若 finally 里没有 return 或没有能够终止程序的代码,执行完 finally 之后再执行 return 结束方法。
若 finally 里有 return 或含有能够终止程序的代码,执行完 finally 之后结束,不执行 return。
在抛出异常的情况下原理也是一样的,把上面说到的 try 换成 catch 去理解就 OK 了,即catch中无论是返回还是抛出异常,最终返回的均是finally中的结果,除非finally无返回。
异常体系(父类Throwable )
java.lang.Throwable 是java中异常的基类,通过Throwable 的集成实现关系可以看出, Error 、Exception 都是继承与Throwable,所以Throwable是java语言体系中异常的超类(父类)。
(1)检查性异常
可查异常:Exception 中非运行时异常,不处理编译不通过,可预见,不做处理,线程中断。try catch 捕获 或者 throws 向上抛出。
(2)非检查性异常(Error、运行时异常 RuntimeException及其之类)
编译器不要求强制处置
分为Error 及运行时异常及其之类
运行时异常及其之类可以在程序中捕获也可以不做捕获,编译都可以通过,尽可能的注意程序逻辑避免运行时异常(NullPointerException、IndexOutOfBoundsException)
如果运行过程中发生非检查性异常,处理的办法是找到发生异常的错误代码或者服务器硬件资源问题处理掉,而不是捕获,这实际上是java多异常做的扩展、容错
(3)Error
-
Error是程序无法处理的错误,所以Error异常是不需要捕获的
2)Error异常是不应该发生的异常情况,所以在程序编译时是不被检查的(非检查性异常)
3)程序一旦发生Error异常,线程停止,web项目通常会报500页面(OutOfMemoryError、ThreadDeath、NoClassDefFoundError)
4)一个设计合理的程序是不应该出现Erro错误的,一旦出现也不需要用程序补救的方式来处理Error异常
(4)Exception
-
程序本身可以处理
2)分为运行时异常和非运行时异常,运行时异常为非检查性异常,非运行时异常为检查性异常
3)当程序中出现非运行时异常时(Exception中除RuntimeException及其之类之外),要不捕获、要么向上抛出throws,否则线程中断
根据业务需求创建自己的异常
(1)java自带异常不能够说明系统发生异常的具体情况
(2)根据业务场景设置可读性强、易于理解、方便系统业务流转的异常(如前后端多场景交互等)
(3)一般通过异常类的名称或内部提示语进行设计,指明用意,便于理解
异常处理策略
(1)如果确定该方法中会发生那些异常并知道如何处理,处理后的业务流程走向也明确,则进行异常捕获并处理
(2)如果不确定该方法中会发生那些异常,或不知道怎么处理这些异常,则向上抛出,又最后一层异常拦截器进行管理
java异常捕获、抛出实现
1、try、catch 、 finally
可以有多个catch。
2、代码实现区如果有异常抛出,则该方法立即创建异常对象(异常的类型已经确定了),并将该异常抛出监控区域外,寻找匹配类型兼容的catch子句,若匹配成功(父类及其本身都可匹配),则执行该catch子句的实现,异常捕获处理结束,如果有finally定义则继续执行finally代码块。
3、只要有一个catch子句匹配成功,则整个捕获过程结束,所以在实现多级catch子句处理时要注意T1、T2、T3…异常类型的归属关系,例如父子关系的异常类型 : Exception是CloneNotSupportedException的父类,而CloneNotSupportedException 是 ServerCloneException 的父类, 根据只要catch匹配整个捕获就结束这个原理,可以得出如果把ServerCloneException 放到第三级catch,把CloneNotSupportedException 放在第二级catch,Exception放在第一级catch,即:
try {
//异常监控区或叫作代码实现区
// 程序业务实现代码
} catch (Exception t1){
// 捕获异常类型为T1的异常
} catch (CloneNotSupportedException t2){
//捕获异常类型为T2的异常
} catch (ServerCloneException t3){
//捕获异常类型为T3的异常
} finally{
//最后处理实现,不管异常是否捕获都会执行的代码
}
后两级catch子句永远都不会被执行,因为第一级永远会优先于后两级匹配,所以要按异常类型级别从低到高的顺序排放catch子句,即ServerCloneException 、CloneNotSupportedException 、Exception
4、finally块也不是肯定会执行的,以下情况不会执行:
finally里发生异常时,finally执行中断
在try或者catch里执行了System.exit(),finally也不会再执行了
由于服务器硬件资源引起的线程死亡也会导致finally不能执行
5、抛出异常 throws throw
(1)throws
java代码抛出异常使用throw (任何java代码都可以抛出)
方法抛出异常使用throws ,且可以同时抛出多个异常
异常可以不断向上抛出,直到最后一层调用方法,即最后一层调用方法必须处理,否则发生错误
方法覆盖,覆盖方法抛出的异常类型必须是被覆盖方法所声明异常的同类或子类,例如接口声明方法是IndexOutOfBoundsException,而实现类汇总覆盖方法抛出的异常类型为Exception,此时程序编译报错
(2)throw
在java代码中以throw 抛出Throwable类型的异常实例对象
throw 一旦执行,该方法体立即停止运行(throw后面的代码不会再执行了)
throw 抛出异常类型后,本方法的catch子句或上层各级调用方法的catch子句开始匹配该异常类型,直到匹配成功后,开始执行catch子句代码实现,如果没有匹配到合适的catch子句,最后交由JVM处理,打印异常信息且导致该线程停止工作
原文链接:https://blog.csdn.net/suoyanming/article/details/89191135
原文链接:https://blog.csdn.net/hejingyuan6/article/details/51296904