目录
1、概念
java异常是程序运行中非预期的各种状况,比如:网络连接失败、参数非法、找不到文件等等。
异常是一个事件,它打断了程序的正常执行流程。
java异常都是对象,是Throwable子类的实例。
java异常类层次结构图如下:
2、java异常中对象解释
Throwable
它由Error、Exception两个子类,二者是java异常处理重要的子类,且有其它子类
Error
不可查。
指正常情况下不太可能出现的情况,Error一般会导致程序(比如JVM自身)处于非正常、不可恢复的状态。
常见的Erro有OutOfMemoryError、StackOverFlowError,都是Error的子类。
一般不处理Error 原因是:既然是Error,那么它首先不容易处理;另外,都Error了,要让代码守护者手工修改代码,把问题暴露出来
Exception
分为可检查异常(编译器要求必须处理的异常,又称编译异常)、不检查异常(编译器没强制要求处理的异常,又称运行时异常RuntimeException)。
可检查异常在源代码里必须进行显示的捕获处理,这是编译期检查的一部分,比如IOException、SQLException,以及用户自定义异常,一般情况用户不自定义可检查异常。
不检查异常是运行时异常,类似NullPointerException、ArrayIndexOutOfBoundsException等,是可以避免的代码逻辑错误,可根据实际需要,通过判断进行捕获,在编译器不会做强制要求。
运行时异常
RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException。
运行时异常是不检查异常,程序中可以选择捕获处理,也可不处理,暴露出来,让程序员发现并修改该错误。
其特点是:Java编译器不检查它,程序中出现这类问题即使没有用try-catch捕获,也没用throws子句抛出它,也会编译通过。
非运行时异常
是检查异常,又称为编译异常,是RuntimeException以外的Exception。
这类异常是程序必须进行处理的异常。如果不处理,程序就会编译不通过。如IOException、SQLException等以及用户自定义的Exception。
一般不建议自定义检查遗产。
3、异常处理机制
java中异常处理的机制为 1)抛出异常, 2)捕获异常
java规定,对于可查异常必须捕获、或者声明抛出;可以忽略不可查的RuntimeException和Error。
抛出异常
当方法运行出错,方法创建异常对象(throw new Exception***),运行时系统负责寻找处理异常的代码块并执行。
捕获异常
方法抛出异常后,运行时系统寻找合适的异常处理器(exception handler)。
潜在的异常处理器是异常发生时存留在调用栈中的方法集合。
当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为找到了合适的异常处理器。
运行时系统从异常发生处开始,回查调用栈中的方法,寻找合适的异常处理器,当运行时系统遍历调用栈,而未找到合适的异常处理器时,则系统终止运行。
总之,对于可检查异常,java要求
必须有一个方法捕获、或者将异常声明抛出(throws)。即,如果一个方法选择不捕获异常,那么它必须声明将该异常抛出。
对于不检查异常,java要求
为了更合理、更容易的实现应用程序,java允许忽略运行时异常,交由java运行时系统自动抛出。
对于不可查异常,java要求
对于方法中可能出现的Error,如果在该方法中不捕获,那么java也允许不做任何抛出声明。因为,Error异常一般是无法挽救的问题,比如OOM,stackoverflow等。
4、java中异常语法
抛出异常
method throws Exception1,Exception2,……ExceptionN{
if(……){
throw new Exception1();
}
if(……){
throw new Exception2();
}
}
捕获异常
try{
}catch(Exception exp){
}
try{
}catch(Exception exp){
}finally{
}
5、java捕捉异常后执行顺序
try->catch->finally按顺序执行,就算try、catch中有return,也要在return之前要执行finally。
如果try中抛出异常,而异常是留给上层方法处理,那么在抛出后,仍然运行finally,然后再回溯到上层。
自然,如果try中有return——也算是回溯了,返回值会存在栈中等待,等finally运行之后再回溯。
而如果finally中有return,那么直接从finally中结束方法。
如果在方法中直接结束程序,即调用System.exit()方法,那么就直接结束了,此时finally是不执行的。由此可以认为,特殊情况导致程序的退出是可能导致一些问题的。毕竟finally一般写的是关闭对象、资源的代码。
在下列情况不会以finally作为结束
1)jvm过早终止
try{
System.exit();
}catch(Exception exp){
}finally{
}
2)在finally块中抛出一个未处理的异常
3)计算机由外部引起故障(断电、受病毒攻击等)
6、遇到的异常场景记录
1、ClassNotFoundException
场景说明:
不同的业务开通不同的模型包(包含不同的业务字段),每个模型包中都有相应的jar,用来动态加载。
但是在制作模型包是由于没有按照正确的流程制作,没有编译出jar包,导致线上运行后有些字段没有值,因为解析该部分字段的jar没有加载。
2020-02-26 12:03:14 237 ERROR [com.xxx][DefaultQuartzScheduler_Worker-1] - not found, class name=com.xxx.xxx.Pack_Information
java.lang.ClassNotFoundException: not found, class name=com.xxx.Pack_Information
参考:
https://www.liaoxuefeng.com/wiki/1252599548343744/1319099982413858 #廖雪峰博客
https://blog.csdn.net/qq_38225558/article/details/82020581 #异常案例