当程序没有按照开发人员的意愿正常执行,中途出现错误导致程序中断,出现这种情况,就称为异常.
认识异常的种类,如何处理异常与避免异常.
异常的产生
异常在 Java 程序中一对象的形式存在,当代码执行过程中,出现异常,虚拟机会自动创建一个异常对象,如果没有对该异常对象进行处理就会导致程序中断,不会执行后续代码
异常的分类
异常在程序中有对象的形式存在. 就有相应的类.
所有的异常类,组成了一个"异常家族"
名称 | 说明 | 备注 |
---|---|---|
Throwable | 所有异常的父类 | |
Excpthions | Throwable的子类 | 异常 |
Check Excpthions | 编译时异常或非运行时异常 | 无法通过编译 |
IOExcpthion | Excpthion的子类,属于Check Excpthions | 输入输出异常 |
SQLExcpthion | Excpthion的子类,属于Check Excpthions | SQL异常 |
ClassNotFoundExcpthion | Excpthion的子类,属于Check Excpthions | 找不到类的异常 |
Uncheck Excpthions | 非编译时异常或运行时异常 | 可以通过编译 |
NullPointeExcpthion | Excpthion的子类,属于Uncheck Excpthions | 空指针异常 |
ArithmeticExcpthion | Excpthion的子类,属于Uncheck Excpthions | 数学运算异常 |
IndexOutOfBoundsExcpthion | Excpthion的子类,属于Uncheck Excpthions | 索引超出范围异常 |
Errors | Throwable的子类 | 错误 |
StackOverFlowError | Errors的子类 | 内存溢出错误 |
VirtualMachineError | Errors的子类 | 虚拟机错误 |
OutOfMemoryError | Errors的子类 | 内存溢出错误 |
Error错误
如果出现XXXXError,如:StackOverFlowError,栈空间溢出,无法通过额外的代码解决,只能通过修改源码
Excpthion异常
如果出现了XXXXExcpthion, 如NullPointeExcpthion,空指针异常,可以通过额外的代码解决
1.运行时异常RuntimeExcpthion
如果一个异常类属于RuntimeExcpthion异常类的子类,称为运行时异常,可以不用处理可以通过编译,在运行时可能抛出异常对象
常见运行时异常 | 说明 | 出现的情景 |
---|---|---|
NullPointeExcpthion | 空指针异常 | 用空对象null调用属性或方法时 |
ArrayIndexOutOfBounds | 数组下标超出范围 | 数组下标超出范围 |
NumberFormatExcpthion | 数字格式异常 | 使用包装类调用parse方法做转换时,无法将参数转换 |
InputMismatchException | 输入不匹配异常 | 使用Scanner接收输入的数据与预定的数据类型不匹配时 |
ClassCastException | 类转换异常 | 当某个对象无法转换为另一个类型时 |
ArithmeticException | 数学运算异常 | 当0作为分母时会抛出该异常(违反数学运算规则时) |
2.编译时异常
如果一个异常类属于Excpthion异常类的子类,称为编译时异常,无法通过编译,必须处理异常后才能编译运行.
常编译时时异常 | 说明 | 出现的情景 |
---|---|---|
SQLException | 数据库SQL相关异常 | 在操作数据库是 |
IOException | 输入输出流异常 | 使用流对象时 |
FileNotFoundException | 文件未找到的异常 | 方法的参数为文件时 |
处理异常
通常所说的处理异常,是指处理Exception类的子类异常.
处理异常的目的,就是保证程序正常执行.
方式一:try=catch-finally语句
这种方式处理异常,无论会不会抛出异常,都能让程序正常执行
try{
//可能出现异常的代码
}catch(异常类 异常对象){
//如果出现异常对象,且与catch小括号中的异常类型匹配,就会执行这里的代码
}catch(异常类 异常对象){
}finally{
//无论程序是否会抛出异常,都要执行的代码
}
执行流程:先执行try中的代码,当出现异常时,与后续catch中的异常类型经行匹配,如果匹配到对应的类型或异常父类型,执行catch中的代买,无论程序是否会抛出异常,都要执行finally中的代码
try catch finally 都不可以单独使用,必须互相配合使用
当try中的代码执行出错时,不会在再执行try中出错之后的代码
范围最大的异常需要放在最后的catch(异常类 异常对象)中,
如catch(Exception e)
在try中定义的内容,无法再try之外使用
在try中使用return时,不会影响finally的执行.(finally是优先于return的)
final finallly finalize的区别
final 是一个修饰符,被final修饰的属性称为常量,方法不能被重写,类不能被继承
finallly是try catch finally结构中的关键字,无卵是否抛出异常,都会执行finallly中的代码
finalize是一Object类中的方法,finalize()在某个对象回收前调用的方法
方式二: throws关键字
这种方式,可以让编译时异常通过编译.
在定义方法是,通过该关键字声明可能抛出的异常.
用法: 方法的参数部分之后添加上 "throws"异常类型1.异常类型2.....
public class Test{
//这是该方法就会有一个声明: 该方法可能会抛出异常
public void fun() throws InterrupExcption {
//这句代码写完后,会报错,因为sleep()方法可能会抛出InterrupExcption异常,
//属于编译时异常,必需要处理
Thread.sleep(500);
}
}
throw和throws
throws表示用于声明方法可能出现的异常,使用时卸载方法的小括号之后
public void fun() throws InterrupExcption {
Thread.sleep(500);
}
throw用于手动抛出异常对象,使用时,写在方法体中,常用于满足某种情况是,强制中断程序
用法:throw 异常对象;
public void fun(){
for(int i=0;i<10;i++){
if(i==5){
throw //需要抛出的异常
}
}
}
自定义异常
如果需要在某种情况下中断程序,可以自定义一个异常类,再通过throw关键字手动抛出
自定义异常步骤
1.自定义一个类,随便继承一某个异常类
如果继承的时RuntimeException,表示自定义的异常属于运行时异常,该异常对象可以不用处理
如果继承的时非RuntimeException,表示自定义的一场属于编译时异常,该异常对象必须要处理
2.可选操作,定义带参构造方法,参数为异常信息,该构造方法调用父类中的构造方法