1.异常概念
异常就是程序中发生由于硬件设备问题、软件设计错误等导致程序异常事件,比如整数除0溢出、数组下标越界、指定数组长度为负、文件找不到等,这些事件的发生将阻止程序的正常运行。为了加强程序的健壮性,程序设计时,必须考虑到可能发生的异常事件并做出相应的处理。
2.异常种类:
A:Java中的异常类定义了程序中遇到的轻微的错误条件。(Exception)
B:Error 是 Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题。因此大多数应用程序都不应该试图捕获它。因为这些错误可能是再也不会发生的异常条件。
C: 每个JAVA程序运行时系统都会自动引入java.lang包,故无需使用import语句导入它
3.异常捕捉格式:
try{
//可能产生异常的代码段
}catch(异常类型1 e){
//处理异常
}catch(异常类型2 e){
//处理异常
} finally{
//无论有无异常都将执行的代码(任何情况都会执行)
}
可能产生的异常代码段的示例:
运行期异常:
//ArithmeticException
int i = 10 / 0;
int i2 = Integer.parseInt("a");
int[] array = [1,2,3];
array[10]
String str = null;
str.subString(0);
//非运行期异常
new FileInputStream(new File("随便写一个不存在的文件"));
//ParseException
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss SSS").parse("2018-03-20 05:29:23 133");
3.1.一个try语句可以跟多个catch语句。
3.2.catch异常时,先捕捉子类异常,再捕捉父类异常。否则会编译无法通过,报无法到达的捕捉块错误。
3.3.try,catch,finally必须紧跟,中间不能写除了注释之外的任何代码。
3.4.catch不能和finally同时省略。
4.throw和throws
throws :
4.1.throws(声明方法体会抛出哪些异常),用于声明方法体所抛出的异常,作用在方法上面。
4.2.throws子句中同时可以指明多个异常,之间用逗号隔开。
4.3.如果声明了要抛出的异常,则本方法可以不处理,而由调用者处理。
4.4.throws在向上抛的时候,可以向上抛抽象的异常(异常子类的父类)。
4.5.若代码显式向上throw 异常时,则必须显式声明throws异常。
4.6. throws和throw的区别
throws(声明方法体会抛出哪些异常),用于声明方法体所抛出的异常,作用在方法上面。
抛出异常(throw),用于向上抛异常,作用在catch语句当中。
5.try cath工作流程:
5.1.程序正常执行,没有抛出异常的情况下catch语句块是不工作的。
5.2.若程序抛出异常,立即中止执行。
5.3.若捕捉了此异常,则执行catch当中的语句,catch语句执行完成,恢复执行,但仅向catch块后面顺序执行。
5.4.若没有catch语句块捕获此异常,则异常沿着方法的调用栈一直向上传播。如果传播过程中一直没有catch语句块捕获,最终由main方法抛出,由JAVA运行时环境(JRE)来处理。
5.5.若捕捉了异常,却再次抛出。同第4条。
6.finally:
从try catch流程能看出,一旦异常抛出,其后面的代码都不再执行,而是进入了异常处理程序,如果没有异常处理程序,异常沿着方法的调用栈一直向上传播,在某些情况下不能满足需求。例如:打开了一个资源,无论如何都要释放掉。否则占用资源(文件,数据库),其它程序将不能使用。更有甚者有可能引起整个系统的崩溃,例如更新系统,更新到一半抛出异常之后,未经还原就直接退出完成,客户欲哭无泪。
finally可以保证离开try-catch语句之前执行,将打开的资源释放掉(即使是有return也会在return之前执行)。但也有几种特殊情况可能会中断finally语句的执行,例如:
1.finally块当中的语句本身产生了异常。
2.执行finally语句块的线程死亡。
3.在finally语句块中执行了System.exit(0);
4.计算机掉电。
7.方法重写对抛出异常声明的约束
声明抛出异常如同访问修饰符一样,也是方法声明的组成部分,所以方法的重写对异常的抛出也有限制。如果方法被重写,要求重写后的方法一定不能声明抛出新的捕获异常,或比原方法范畴更广的异常。
根据替代性原则,子类对象要能够替代父类对象。当调用父类方法时不需要处理的异常,在调用子类中同样的方法时就要处理,这就无法替代了。
异常流程图
1.Throwable 类是 Java 语言中所有错误或异常的超类。
2.只有当对象是此类(或其子类之一)的实例时,才能抛出。
3.只有当对象是此类(或其子类之一)的实例时,才可以是 catch 子句中的参数类型。
Error 用于指示合理的应用程序不应该试图捕获的严重问题。因此大多数应用程序都不应该试图捕获它。因为这些错误可能是再也不会发生的异常条件。
无需在其 throws 子句中声明可能抛出但是未能捕获的 Error。
Exception 指出了合理的应用程序想要捕获的条件。
如果方法没声明throws 异常,那么它必须在方法体内被捕获(RuntimeException 除外)。
RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。
可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明