概念
- 程序发生了不正常的情况
Throwable
- Error
程序无法处理的异常,如内存溢出
- Exception
程序可处理的异常,用过catch捕获
编译时异常:一般指语法错误,根据编译器提示改正
必须显示处理
运行时异常:
1.受检异常:编译器提出对异常的处理
常见受检异常
ClassNotFoundException
IOException
SQLException
FileNotFoundException
2.非受检异常:代码不需要强制进行捕获处理
常见非受检异常
RuntimeException
NullPointerException
IndexOutOfBoundsException
ArrayIndexOutBoundsException
StringIndexOutOfBoundsException
- 所有异常的父类是Throwable类
JVM默认如何处理异常
- 我们未做任何处理时,JVM默认处理
- JVM将异常的名称、原因及出现的问题等信息在控制台输出,同时结束程序
try{}catch(){}
- 格式
try{
可能出现问题的代码
}catch(异常类型 变量名){
针对问题的处理
}
- try:监控有可能异常的代码块
try块中一旦发现异常直接跳出try块到catch块中,然后继续执行try-catch以外的代码
try后可以有0个或多个catch,但0个时必须接finally
- catch:捕获指定异常类型对象
必须要有内容,哪怕是一个简单的提示
- getMessage():错误信息
- printStackTrace():输出红色报错信息到控制台,并且程序可以继续运行
能明确的异常尽量明确
异常类出现父子关系时,父要在后面捕获
catch(XXX1 e){
}catch(XXX2 e){}
多异常处理:多个异常间必须时平级关系
catch(XXX1|XXX2 e)
- try{}catch{}会增加额外的开销
finally
- finally必须和try块一起使用,不能单独存在
- 无论try/catch发生什么 finally块一定会执行
特殊情况:finally之前JVM退出了(System.exit(0)),程序所在线程死亡,CPU关闭
- 必须执行的代码块,如关闭资源(先要判断该资源是否为空)
finally{
if(in!=null){
in.close();
}
}
- 应用情景
当异常发生时,程序可能会意外中断,有些被占用的资源得不到清理
- 思考题
throws
- 方法中不对检查异常进行处理(catch块)此时就必须抛出方法外,交给主调函数处理(try-catch)
主调函数:调用此函数的方法
- 格式:throws 异常类名
- 注意
必须跟在方法的括号后
尽量不要再main方法上抛出异常
将异常抛出方法之外
- 为了告诉调用者,注意了,我有问题
throw
- 在方法中手动抛出可能发生的异常
- 格式:throw 异常对象
- 注意
必须对异常进行处理
处理方式一:try-catch
处理方式二:throws抛出异常
思考题
异常处理方式选择
- 后续程序需要继续运行---->try
- 后续程序不需要继续运行---->throws
用户自定义异常
- Java不可能全部的异常都考虑到
- 自定义异常继承自Exception(编译时)或RuntimeException(运行时)
异常类的继承结构体系
- 异常的基类为Exception,所有异常都必须直接或者间接继承它
- Exception被大多数异常继承
- 大多数异常没有重写方法
常见异常类型
- Exception 异常结构层次的根类
- RuntimeException 许多Java.lang异常的基类
- ArithmeticException 算数异常
- IllegalArgumentException 方法接收到非法参数
- ArrayIndexOutOfBoundsException 数组下标越界
- NullPointerException 访问空引用
- ClassNotFoundException 不能加载所需的类
- ClassCastException 类型转换异常
- NumberFormatException 字符串转数字失败或数字格式化异常
- IOException I/O异常的根类
- FileNotFoundException 找不到文件
- EOFEException 文件结束
JDBC编程的异常类型
- SQLException
- SQLWarning
注意事项
- 子类重写父类方法时,子类的方法抛出相同的异常或父类异常的子类 (父亲坏了,儿子不能比父亲更坏)
- 如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
- 如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws