四十二、异常
作者:互联网
1、概述
异常就是程序出现了不正常的情况。程序在执行过程中,数据导致程序不正常,最终会导致JVM的非正常停止。
注意:语句错误不算在异常体系中。
异常的存在形式:
异常有类型之分,比如我们之前有接触过的比较熟悉的 数组越界异常、空指针异常、类型转换异常。当程序中产生异常时,其实就是在异常的位置创建了一个该异常的对象,该对象携带了相关的异常信息。因此,异常就是 Java 中提供的类的对象。
程序中异常产生后,是如何处理的:
程序中一旦产生异常, 首先会中断向下执行。异常的传递要根据处理方式(而定,如果没有处理,默认是将异常传递给本方法的调用者。不断往回传递,直到JVM收到该异常,此时程序终止执行。
2、异常体系
Throwable
Error: 严重问题,通过代码无法处理。比如:内存溢出
Exception: 称为异常类,它表示程序本身可以处理的问题
RuntimeException及其子类: 运行时异常。(空指针异常,数组索引越界异常)
非RuntimeException及其子类: 编译器必须处理的,否则程序不能通过编译。(日期格式化异常)
3、JVM处理异常
如果程序出现了问题,我们没有做任何处理,最终JVM会做默认的处理。那jvm是如何处理的?
- 把异常的类型,原因,位置打印在控制台
- 程序停止执行
注意:程序中出现了异常,会在当前位置创建此异常的对象,对象中包含了异常的信息,并把此异常交给本方法的调用者处理。
4、声明异常——throws
格式:
【格式】
修饰符 返回值类型 方法名(参数列表) throws 异常类型1 , 异常类型2...{...}
【举例】
public void show(int i) throws NullPointerException,IOException{...}
作用:
- 表示告知调用者当前的方法可能会出现某些异常,使用是需要注意。
- 如果当前方法没有出现任何异常,那么代码会正常执行。
- 如果当前方法中出现了异常,会把异常交给本方法调用者处理(甩锅)。
注意事项:
- 编译时异常因为在编译时就会检查,所以必须要写在方法后面进行显示声明。
- 运行时异常因为在运行时才会发生,所以在方法后面可以不写。
- 如果声明多个异常有子父类关系,那么只要声明一个父类即可(多态)。
5、抛出异常——throw
思考: 以前出现了异常,虚拟机帮我们创建一个异常对象,抛给调用者。但是如果我们需要自己手动创建一个异常对象该如何写?
5.1 格式
修饰符 返回值类型 方法名(参数列表){
throw new 异常对象();
}
注意:
- 抛出异常的格式必须在方法的内部完成
抛出异常的意义所在
- 在方法中,当传递的参数有误,没有继续运行下去的意义了,则采取抛出处理,表示让该方法结束运行。
- 告诉调用者方法中出现了问题。
6、throws与throw区别
throws:
- 用在方法声明后面,跟的是异常类名
- 表示声明异常,调用该方法有可能会出现这样的异常
throw:
- 用在方法体内,跟的是异常对象名
- 表示手动抛出异常对象,告知调用者数据传入有误
7、捕获异常try-catch
7.1 try-catch介绍
之前的声明或者抛出都是将异常传递出去,让调用者知道异常信息
而捕获处理是本方法内部进行处理,能够阻止异常的传递,从而保证程序能够继续往下执行
7.2 捕获异常格式
try{
try中存放可能会出现问题的代码
代码...
}catch(异常类型){
处理异常的方案
}
其他代码
7.3 捕获异常执行方式
-
如果try中没有遇到问题:
从上往下依次执行,catch中不执行
-
如果 try 中代码遇到了问题:
下面的代码不会执行,会拿当前异常对象和异常类型匹配,匹配成功执行处理异常代码
-
如果出现的问题没有被捕获:
如果异常没有捕获到。虚拟机会帮助我们处理
-
处理多个异常
-
多个异常,每个异常单独处理
try{ 异常1 }catch(异常1){} try{ 异常2 }catch(异常2){}
-
多个异常,一次捕获,多次处理
注意:如果多个异常有继承关系,父类异常要放在子类异常后面。建议使用因为不用异常以后可能有不同处理的方案
try{ 异常1 异常2 }catch(异常1){ }catch(异常2){ }
-
多个异常,异常一次捕获,一次处理
try{ 异常1 异常2 }catch(Exception e){ }
-
8、常用方法
Throwable的成员方法
方法名 | 说明 |
---|---|
public String getMessage() |
返回 详细信息原因 |
public String toString() |
返回 类名 + 原因 |
public void printStackTrace() |
把异常的错误信息输出在控制台 打印类名 + 原因 + 位置 |
9、finally
9.1 关键字介绍
finally关键字,表示最终要执行的,不能单独使用,需要结合try-catch使用。
通常用于一些资源的释放,比如后续学到的IO流知识,流资源的释放
9.2 格式
try {
1 xxxxxxx
2 xxxx异常
//3 释放资源(当有异常时不会执行)
} catch (异常) {
} finally {//一定会执行
//释放资源的代码 对象.close();
}
分析:
- 如果3行代码进行释放资源,在2行代码产生异常时将无法执行。
- 如果将释放资源的代码放到finally代码块中,就能保证一定能执行。除非 JVM 结束执行(比如之前调用的
System.exit(0)
)。
10、自定义异常
10.1 概述
在JDK中的异常类型,不满足实际的业务需求时,就可以自己定义异常。自定义异常存在的意义:就是为了让控制台的报错信息更加的见名之意。
10.2 实现步骤
public class AgeOutOfBoundsException extends RuntimeException{
public AgeOutOfBoundsException(){
}
public AgeOutOfBoundsException(String message){
super(message);
}
}
① 定义异常类
② 写继承关系
③ 空参构造
④ 带参构造
10.3 注意
- 如果要自定义编译时异常,就继承Exception。
- 如果要自定义运行时异常,就继承RuntimeException。
11、小结
异常出现分两种:① 系统出现的异常。② 手动制造出来的异常 throw
异常分两种:① 编译时异常。 ② 运行时异常。
解决异常分:①throws 抛出,抛给父类。 ② 捕获,使用 try-catch
throws 如果都不进行异常处理,最终抛给JVM虚拟机。所以系统会强制停止。它的存在只是说明有可能出现异常。
try-catch 当前出现的异常,当前解决。捕捉到异常就在终端上进行显示, 不影响下面代码的执行
编译时异常 必须要进行解决,如果不解决,则不让执行。可以抛出,也可以捕获
运行时异常 在运行时才会报错,可以不选择进行异常处理
标签:处理,方法,try,catch,执行,异常,四十二 来源: https://www.cnblogs.com/6ovo6/p/14969129.html