异常的介绍
异常指的是不正常,指的是程序出现了某些问题。
在Java中所有的问题都可以使用一个类来表示,这个类叫做Throwable。
Throwable是所有异常和错误的父类。
异常的继承体系及分类
Throwable
|–Error: 错误。 是程序中严重的,不可挽回的问题。 相当于人得了绝症。
|–Exception:异常。是程序中轻微的,可以挽回的问题。 相当于人得了感冒。
|–RuntimeException
|–其他子类
运行时异常:RuntimeException以及RuntimeException下的所有子类都是运行时异常;
编译时异常:Exception以及除了RuntimeException外的其他子类都是编译时异常.
throw关键字
作用:手动抛出异常.
格式:
throw new 异常类名();
注意:使用throw向外抛出的一定要是一个异常对象。
在创建异常对象时可以在构造方法中传递一个字符串,该字符串表示异常信息。
Objects判断为空的方法
在工具类Objects中有一个方法,可以验证对象是否为空。
static <T> T requireNonNull(T obj):判断参数对象是否为空。如果参数对象是空,那么抛出空指针异常。
throws关键字的使用
throw:用来手动抛出异常。
throws:用来进行异常声明,声明某个方法有可能会抛出异常。
格式:
修饰符 返回值类型 方法名(参数列表) throws 异常类名 {
方法体;
return 返回值;
}
注意:
1. 如果在方法内抛出了编译时异常,那么必须要使用throws进行声明
2. 在调用使用throws声明异常的方法时,调用者方法如果不解决这个异常(try…catch),必须也叫使用throws进行声明
3. 如果在方法中抛出的是运行时异常,可以不使用throws进行使用。
4. 如果方法中有可能抛出多个异常,那么我们需要使用throws进行多个异常的声明.
5. 如果在方法中有可能抛出多个异常,那么我们也可以直接使用throws声明这些异常的父类异常.
try…catch解决异常
如果想要解决掉异常,而不是将异常向外抛,可以使用try…catch语句(捕获处理)
格式:
try {
可能出现异常的代码
} catch(异常类名 变量名) {
出现异常后执行的代码
}
如果try中引发的异常和catch小括号中写的异常类名相同,那么catch可以捕获到该异常。
执行流程:
第一种情况:try中的代码没有任何异常,那么代码会跳过catch继续向下执行。
第二种情况:try中的代码有异常并且catch捕获到了这个异常,那么代码会从try直接跳到catch中。
第三种情况:try中的代码有异常但是catch没有捕获到这个异常,这个异常会依旧向外抛。
两种处理异常的方式
向外抛(甩锅):throw throws
解决异常: try…catch
finally代码块
格式:
try {
【A】可能会出现异常的代码
} catch(要捕获的异常类名 变量名) {
【B】出现异常后执行的代码
} finally {
【C】一定会执行的代码
}
finally代码块的特点:finally代码块的内容无论如何都会执行。
执行流程:
第一种情况:如果try中的代码没有异常,执行流程为【A】【C】
第二种情况:如果try中的代码有异常,并且catch捕获到了这个异常,执行流程为 【A】【B】【C】
第三种情况:如果try中的代码有异常,但是catch没有捕获到这个异常,执行流程为 【A】【C】向外抛出异常
finally代码块的使用场景:
一定要执行的代码放在finally代码块中,比如后期释放资源的操作(IO流中的关闭流,JDBC关闭连接)都是在finally代码块中执行的.
编译时异常和运行时异常的区别
编译时异常:在编译时期必须要进行处理(try…catch或throws)
运行时异常:在编译时期,可以处理,也可以不处理。
继承关系中方法重写时的异常处理
在方法重写时,如果父类方法没有抛出异常,那么子类重写的方法也不能抛,如果子类方法有异常,只能try…catch
在方法重写时,如果父类方法抛出了异常,那么子类方法可以抛,也可以不抛。如果子类方法向外抛,要么抛出和父类方法异常一样的异常,要么抛出父类方法异常的子类异常。
注意:上面所说的规则只适用于编译时异常。
多异常处理的注意事项
try后面可以追加多个catch,多个catch可以进行多异常的捕获处理
格式:
try {
可能出现异常的代码;
} catch(要捕获的异常类名 变量名) {
出现异常后执行的代码;
} catch(要捕获的异常类名 变量名) {
出现异常后执行的代码;
} catch(要捕获的异常类名 变量名) {
出现异常后执行的代码;
}
执行流程:
第一种情况:如果try中的代码没有异常,所有的catch都不执行。
第二种情况:如果try中的代码有异常, 哪个catch先捕获到异常,那么就执行哪个catch后面的语句。
第三种情况:如果try中代码有异常,但是所有的catch都没有捕获到,那么这个异常依旧会向外抛。
注意:在进行多catch异常处理时,父类异常不能放在子类异常的前面,因为父类异常的catch会拦截掉所有能捕获到的异常。
Throwable中操作异常信息的方法
在Throwable中有一些方法可以获取异常信息。
void printStackTrace():使用标准的错误流将异常信息输出到控制台【非常详细的异常信息】
String getMessage():获取异常信息的字符串【简短的异常信息】
上面的这些方法要通过异常对象去调用【要通过捕获到的异常对象调用】
自定义异常
如果我们定义的类继承的是编译时异常,那么这个类就是编译时异常。
如果我们定义类继承的是运行时异常,那么这个类运行时异常。
一般来说,定义编译时异常都会继承Exception,定义运行时异常都会继承RuntimeException