Java异常
Java异常1. 什么是异常2. 异常的分类3. 论叔侄之间的亲密关系4. 异常处理5. finally语句6. 一些注意事项7. 复习题
1. 什么是异常
在Java中,异常是一种对象,表示阻止正常运行的程序执行的错误或者情况。
更通俗来说就是经常让我们程序崩溃的东西,比如刚刚我的代码就挂了
异常都有有哪些类型,都一定会弄死我的小可爱么
我该怎么抢救一下 小可爱
2. 异常的分类
Throwable类是所有异常类的父类,所有的异常都是它的后代。
(Throwable:我 ,是你爸爸,或者爷爷)-
Error类:system error,描述的是系统内部错误,比如虚拟机炸了啊(VirtualMachineError)什么的。
死亡率:百分之百
Exception类:由程序和外部环境引起的错误,可以被程序捕获和处理。也就是说,这种异常!可以抢救一下! 小可爱:我觉得我还可以抢救一下
(族谱 )
3. 论叔侄之间的亲密关系
上回说到,Error 和Exception 是一对亲兄弟,都有着好几个儿子。其中Exception 的儿子RuntimeException 就格外喜欢他的叔叔Error,天天想着溜到他们家,就是这个样子
上天也被他们之间的 爱情 感动到了,于是为了让他们近亲结婚 ,免去了婚检,从此Error 和RuntimeRxception 被划分为免检异常 ,其他异常为必检异常 。 这种关系是不正常的,所以免检异常是在程序中必须纠正的逻辑错误 。 PS:前面我发的那个截图就属于免检异常。
- 免检异常:Java语言不强制要求编写代码捕获或声明免检异常。可能在程序的任何一个地方出现。
- 必检异常:编译器强行要求程序员检查并通过try-catch语句处理,或者在方法头进行声明。
4. 异常处理
假如我们在工作中遇到问题该怎么处理?一般来说有两种情况,第一种就是自己觉得能解决就自己处理了,当自己解决不了,那就上报给上级找个大腿来解决。对Java来说同样是如此。
-
声明异常
当一个方法可能会抛出必检异常,则必须在方法中头中声明。throws后面可跟多个异常。如下所示:
public void method() throws IOException
何时需要声明异常?
当方法中需要抛出异常或者说该方法调用的子方法有抛出异常,但是没有对该异常进行捕获处理
-
抛出异常
a. 检测到错误的程序可以创建一个合适的异常类型示例并抛出它。示例:
IOException ex = new IOException();
throw ex;
或者是:
throw new IOException();
注意声明异常和抛出异常关键字的区别
b. 抛出链式异常,同原始异常一起抛出一个新异常(带有附加信息),称为链式异常。
try{
p1();
}
catch(Exception ex){
throw new Exception(ex); //在捕获到异常后,带着这个异常抛出一个新异常
//若输出异常信息,会先显示该方法抛出的异常,再显示p1产生的异常
}
-
捕获异常
在使用中,将可能产生异常的语句放到try里面,若产生异常则会跳过剩下的语句,执行相应的catch部分的语句。
注意:捕获多个异常时,若父类的catch块在子类之前,则会导致编译错误。如下面,若ex1是ex2的父类则会出错。
try {
statements; //可能产生异常的语句放入try里面
}
catch (Exception1 ex1){
handle for ex1; //对第一个异常进行处理
}
catch (Exception2 ex2){
handle for ex2; //对第二个异常进行处理
}
-
“上级”(调用者)对必检异常的处理:
若方法中声明了一个必检异常,则调用者必须在try-catch语句中执行,或者在调用者方法头中声明异常(即再把异常交给它的上级)。例如:若p2()可能会抛出一个必检异常(以IOException为例),方法p1()调用p2,则应该如下处理:
//捕获p2 的异常
void p1(){
try{
p2();
}
catch(IOException ex){
...
}
}
//抛出p2的异常
void p1() throws IOException(){
p2();
...
}
5. finally语句
若希望无论是否出现异常,都执行某些代码,则使用finally。(例如各种连接的关闭)
- 使用finally时可以省略catch块
- 即使在到达finally前有return语句,依旧会执行finally的代码
6. 一些注意事项
捕获异常时,尽量不要捕获通用异常,如
catch(Exception e)
,应该捕获特定异常。否则可能会捕获到意想不到的异常,而且也会令他人不易理解自己的代码。对于捕获到的异常不要忽略
记住“Throw early catch late”(早点抛出异常延迟抓取异常)原则,这个原则就是说,应该在异常出现时就将其抛出,抓取应该在能够获取足够信息的时候。简单来说,底层的方法应该更多的抛出异常,异常应该更多的在顶层代码中抓取处理。
异常处理会花费较大的时间和资源,不要用异常处理来做简单的逻辑测试。如非必要,勿用异常
7. 复习题
throw、throws区别
必检异常和免检异常区别
NoClassDefFoundError 和 ClassNoFoundException区别
欢迎关注灵魂画手的公众号!赔我板栗