异常
概念
概念:程序在运行过程中出现的不正常现象。出现异常不处理将终止程序运行。
异常处理的必要性:任何程序都可能存在大量的未知问题、错误;如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失。
异常处理:java编程语言使用异常处理机制为程序提供了异常处理的能力。
分类
Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中。
- Error:JVM、硬件、执行逻辑错误,不能手动处理。
StackOverflowError
OutOfMemoryError - Exception:程序在运行和配置中产生的问题,可处理。
RuntimeException:运行时异常,可处理,可不处理。
CheckedException:检查时异常,必须处理。
还没运行,编译就有异常,叫做检查时异常
常见运行时异常
类型 | 说明 |
---|---|
NullPointerException | 空指针异常 |
ArrayIndexOutOfBoundsException | 数组越界异常 |
ClassCastException | 类型转换异常 |
NumberFormatException | 数字格式化异常 |
ArithmeticException | 算术异常 |
产生与传递
异常的产生:当程序在运行时遇到不符合规范的代码或结果时,会产生异常或程序员使用throw关键字手动抛出异常。
异常的传递:按照方法的调用链反向转递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息,并中断程序运行)。
处理
JVM 的异常处理是通过5个关键字来实现的:
try:执行可能产生异常的代码。
catch:捕获异常,并处理。
finally:无论是否发生异常,代码总能执行。
throw:手动抛出异常。
throws:声明方法可能要抛出的各种异常。
异常处理try…catch
try{
//可能出现异常的代码
}catch(Exception e){
// 异常处理的相关代码,如getMessage()、printStackTrace()
}
会出现三种情况:
- 正常请求
- 出现异常并处理
- 异常类型不匹配
异常处理 try…catch…finally
try{
//可能出现异常的代码
}catch(Exception e){
//异常处理的相关代码,如:getMeasage()、printStackTrace()
}finally{
//是否发生异常都会执行,可以释放资源等
}
finally块是否发生异常都执行,可以释放资源
finally块不执行的唯一情况,退出java虚拟机
异常处理 多重catch
try{
//可能出现异常的代码
}catch(异常类型1){
// 满足异常类型1执行的相关代码
}catch(异常类型2){
// 满足异常类型2执行的相关代码
}catch(异常类型3){
// 满足异常类型3执行的相关代码
}
- 子类异常在前,父类异常在后
- 发生异常时按顺序逐个匹配
- 只执行第一个与异常类型匹配的catch语句
- finally根据需要可写或不写
异常处理 try…finally
try…finally 不能捕获异常,仅仅用来当发生异常时,用来释放资源。
一般用在底层代码,只释放资源不做异常处理,把异常向上抛出。
try{
// 可能出现异常的代码
}finally{
//是否发生异常都会执行,可以释放资源等...
}
声明异常
如果在一个方法体中抛出了异常,如何通知调用者?
throws关键字:声明异常
使用原则:底层代码向上声明或者抛出异常,最上层一定要处理异常,否则程序中断。
抛出异常
除了系统自动抛出异常外,有些问题需要程序员自行抛出异常。
throw关键字:抛出异常
语法:throw 异常对象;
自定义异常
需要继承自Exception或Exception的子类,常用RuntimeException。
必要提供的构造方法:
- 无参构造方法
- String message参数的构造方法
方法覆盖声明异常方法
带有异常声明的方法覆盖:
方法名、参数列表、返回值类型必须和父类相同。
子类的访问修饰符和父类相同或是比父类更宽。
子类的方法,不能抛出比父类更多、更宽的检查时异常。