2022-7-29 第七组 潘堂智 异常的处理
异常概述
什么是异常?Java代码在运行时期发生的问题就是异常。
在Java中,把异常信息封装成了一个类。当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置、原因等)。
Throwable
Throwable 是 Java 语言中所有错误与异常的超类。 Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常情况。
Throwable 包含了其线程创建时线程执行堆栈的快照,它提供了 printStackTrace() 等接口用于获取堆栈跟踪数据等信息
Error(错误)
Error 类及其子类:程序中无法处理的错误,表示运行应用程序中出现了严重的错误。 此类错误一般表示代码运行时 JVM 出现问题。通常有 Virtual MachineError(虚拟机运行错误)、
NoClassDefFoundError(类定义错误)等。比如 OutOfMemoryError:内存不足错误;
StackOverflowError:栈溢出错误。此类错误发生时,JVM 将终止线程。 这些错误是不受检异常,非代码性错误。
因此,当此类错误发生时,应用程序不应该去处理此类错误。按照Java惯例,我们是不应该实现任何新的Error子类的!
Exception(异常)
程序本身可以捕获并且可以处理的异常。Exception 这种异常又分为两类:运行时异常和编译时异常。
运行时异常
都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。 运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,
也没有用throws子句声明抛出它,也会编译通过。
非运行时异常
(编译异常) 是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。
如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
*异常关键字 try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,try语句块内发生异常时,异常就被抛出。
*catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
*finally – finally语句块总是会被执行。它主要用于回收在try块里打开的物力资源(如数据库连接、网络连接和磁盘文件)。只有finally块,执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
*throw – 用于抛出异常。
*throws – 用在方法签名中,用于声明该方法可能抛出的异常。
异常处理
JVM默认处理方式
如果出现异常我们没有处理,jvm会帮我们进行处理,他会把异常的类型,原因还有位置显示在命令行并且还终止了程序,异常后面的代码将不在执行
try {
//需要被检测的语句。
}
catch(异常类 变量) { //参数。
//异常的处理语句。
}
finally {
//一定会被执行的语句。
}
try...catch的执行顺序:
* 首先执行try语句
* 如果发现异常,异常下面的代码不在执行,直接跳入catch语句中,catch语句结束后,整个try...catch结束
* 如果没有发现异常,try语句执行结束后,try...catch直接结束, 不在执行catch语句
throws方式处理异常
抛出去当我们不想处理异常,或者没有能力处理的时候,我们可以选择抛出异常,谁调用方法谁处理异常
throws使用:
权限修饰符 返回值类型 方法名(形参列表) throws 异常类型1,异常类型2….{
}
多异常处理
对代码进行异常检测,并对检测的异常传递给catch处理。对每种异常信息进行不同的捕获处理。
void show(){ //不用throws
try{
throw new Exception();//产生异常,直接捕获处理
}catch(XxxException e){
//处理方式
}catch(YyyException e){
//处理方式
}catch(ZzzException e){
//处理方式
}
}
注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。
Throwable常用方法
String getMessage() 返回此 throwable 的详细消息字符串
String toString() 返回此 throwable 的简短描述
void printStackTrace() 打印异常的堆栈的跟踪信息
-
我们为什么要手动抛异常?
-
因为要配合全局异常处理机制来解决问题
finally使用格式:
try{
}catch(异常类型 异常变量){
}finally{
//释放资源的代码
}
finally不是任何时候都是能执行的,finally遇见如下情况不会执行
在前面的代码中用了System.exit()退出程序。
finally语句块中发生了异常。
程序所在的线程死亡。
关闭CPU。
记住图中的执行顺序:第一个红框里的注解,因为finally 的原因所有是图中的执行顺序。
异常基础的总结:
try、catch和finally都不能单独使用,只能是try-catch、try-finally或者try-catch-finally。
try语句块监控代码,出现异常就停止执行下面的代码,然后将异常移交给catch语句块来处理。
finally语句块中的代码一定会被执行,常用于回收资源 。
throws:声明一个异常,告知方法调用者。 throw :抛出一个异常,至于该异常被捕获还是继续抛出都与它无关。
Java编程思想一书中,对异常的总结。
在恰当的级别处理问题。(在知道该如何处理的情况下了捕获异常。)
解决问题并且重新调用产生异常的方法。
进行少许修补,然后绕过异常发生的地方继续执行。
用别的数据进行计算,以代替方法预计会返回的值。
把当前运行环境下能做的事尽量做完,然后把相同的异常重抛到更高层。
把当前运行环境下能做的事尽量做完,然后把不同的异常抛到更高层。
终止程序。
进行简化(如果你的异常模式使问题变得太复杂,那么用起来会非常痛苦)。
让类库和程序更安全。
本文来自博客园,作者:阿萨德菩提子,转载请注明原文链接:https://www.cnblogs.com/ychptz/p/16533232.html