异常表示不正常的意思,在java中主要指在程序运行阶段产生的错误
异常的分类
- 可检测异常:可检测异常经编译器验证,对于声明抛出异常的任何方法,编译器将强制执行处理或声明规则,不捕捉这个异常,编译器就通不过,不允许编译。
- 非检测异常:非检测异常不遵循处理或者声明规则。在产生此类异常时,不一定非要采取任何适当措施,编译器不会检查是否已经解决了这个异常。
- 自定义异常:为了表示应用程序的一些错误类型,为代码可能发生的一个或多个问题提供新含义。
java.lang.Throwable类是java中所有错误或异常的超类
主要实现子类有:
Error类:表示java运行时环境出现的错误,主要描述一些比较严重的错误,无法通过编程解决的问题
例如JVM内存资源耗尽等
Exception类:表示由于网络故障、文件损坏、设备错误、用户输入非法等情况导致的异常
主要描述一些轻微的错误,可以通过编程来解决的错误
java.lang.Exception类是所有异常的超类,主要分为以下两大类:
RuntimeException类 - 运行时异常类,也叫做非检测性异常。指在编译阶段无法被编译器检测出来的异常
因为普通JVM操作引起的运行时异常随时可能发生,此类异常一般是由特定操作引发。
但这些操作在java应用程序中会频繁出现,因此它们不收编译器检查与处理或声明规则的限制
IOException类和其他异常类 - 检测性异常
当程序执行过程中产生异常并没有手动处理时,则采用默认处理方式,默认处理的方式是:
打印异常名称、异常原因、异常位置等信息并终止程序,导致后续代码无法执行。
RuntimeException类的主要子类:
ArithmeticException类 - 算术异常
ArrayIndexOutOfBoundsException类 - 数组下标越界异常
NullPointerExpection类 - 空指针异常
ClassCastException类 - 类型转换异常
NumberFormatException类 - 数字格式异常(间接子类)
运行时异常的处理
对于绝大多数的运行时异常/非检测性异常都可以采用if()条件判断的方式避免发生。
异常的捕获
try{
编写可能产生异常的语句块;
}catch(异常类型 变量名){
编写针对该类异常的处理语句块;
}
finally{
编写无论是否发生异常都应该执行的语句块;
}
注意事项:
a.当需要catch()多种不同类型的异常时,切记小类型需要放在大类型的上面。(catch(Exception e))
b.finally中通常编写无论是否发生异常都应该执行的代码,因此通常用来善后处理
比如:关闭打开的文件,断开数据库的连接等
执行流程:
try{
a;
b; //表示可能发生异常的语句
c;
}catch(Exception e){
d;
}
finally{
e;
}
当上述代码没有发生异常时的执行流程:a b c e;
当上述代码发生异常时的执行流程:a b d e;
finally
finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序其他部分以前,能够对程序的状态作统一管理。无论try所指定的程序块中是否抛出例外,finally所指定的代码都要被执行
通常在finally语句中可以进行资源的消除工作,如关闭打开的文件、删除临时文件等。
异常的抛出
在某些特殊场合中,对于出现的异常无法直接处理/不便于处理时,就可以选择将该异常转移给该方法的调用者,这种形式叫做异常的抛出
返回值类型 方法名(形参列表) throws 异常类型1,异常类型2,…{方法体;}
如: public void show() throws IOException{…}
方法重写的原则
a. 要求方法名、参数列表、返回值类型相同。
b. 访问权限可以变大,不能变小。
c. 不能抛出更大的异常。
注意:当子类中重写父类的方法时,可以抛出一样的异常、可以抛出更小的异常、可以不抛出异常,但不能抛出更大的异常,以及同级却不一样的异常。
自定义异常
-
自定义类继承Exception类或者其子类,提供两个版本的构造方法,一个是无参的构造方法,另外一个是String类型变量作为参数的构造方法。
-
异常对象的抛出:throw new 异常类型();
如:throw new AgeException(“年龄不合理!”);
thorws声明
程序中会定许多方法,这些方法中可能会因某些错误而引发异常,但不希望直接在这个方法中处理这些异常,而希望调用这个它的方法来统一处理,这时候可以使用“throws”关键词来声明这个方法将会抛出异常。
public void show(String str) throws ParseException{
//代码块;
}
throw语句
当程序发生错误而无法处理的时候,会抛出对应的异常对象,除此之外,在某些时刻,可以自行抛出异常,例如在异常处理结束后,再将异常抛出,让下一层异常处理区块来捕捉,若想要自行抛出异常,可以使用throw关键字。并生成指定的异常对象。