Java异常:你是异常的失落

Java异常:你是异常的失落


1. 什么是异常

在Java中,异常是一种对象,表示阻止正常运行的程序执行的错误或者情况。

​ 更通俗来说就是经常让我们程序崩溃的东西,比如刚刚我的代码就挂了
在这里插入图片描述

  • 异常都有有哪些类型,都一定会弄死我的小可爱么
  • 我该怎么抢救一下 小可爱

2. 异常的分类

  1. Throwable类是所有异常类的父类,所有的异常都是它的后代。(Throwable:我 ,是你爸爸,或者爷爷)

  2. Error类:system error,描述的是系统内部错误,比如虚拟机炸了啊(VirtualMachineError)什么的。

    死亡率:百分之百

  3. Exception类:由程序和外部环境引起的错误,可以被程序捕获和处理。也就是说,这种异常!可以抢救一下!
    小可爱:我觉得我还可以抢救一下

     							(*族谱* )
    

在这里插入图片描述


3. 论叔侄之间的亲密关系

​ 上回说到,ErrorException 是一对亲兄弟,都有着好几个儿子。其中Exception 的儿子RuntimeException
就格外喜欢他的叔叔Error,天天想着溜到他们家,就是这个样子

在这里插入图片描述

​ 上天也被他们之间的 爱情 感动到了,于是为了让他们近亲结婚 ,免去了婚检,从此ErrorRuntimeRxception ** 被划分为免检异常** ,其他异常为必检异常 。 这种关系是不正常的,所以免检异常是在程序中必须纠正的逻辑错误
PS:前面我发的那个截图就属于免检异常。

  • 免检异常:Java语言不强制要求编写代码捕获或声明免检异常。可能在程序的任何一个地方出现。

  • 必检异常:编译器强行要求程序员检查并通过try-catch语句处理,或者在方法头进行声明。


4. 异常处理

​ 假如我们在工作中遇到问题该怎么处理?一般来说有两种情况,第一种就是自己觉得能解决就自己处理了,当自己解决不了,那就上报给上级找个大腿来解决。对Java来说同样是如此。

  1. 声明异常

    ​ 当一个方法可能会抛出必检异常,则必须在方法中头中声明。throws后面可跟多个异常。如下所示:
    public void method() throws IOException

    何时需要声明异常?

    当方法中需要抛出异常或者说该方法调用的子方法有抛出异常,但是没有对该异常进行捕获处理

    1. 抛出异常

    ​ a. 检测到错误的程序可以创建一个合适的异常类型示例并抛出它。示例:

    IOException ex = new IOException();
    throw ex;

    ​ 或者是:

    throw new IOException();

    ​ **注意声明异常和抛出异常关键字的区别 **

    ​ b. 抛出链式异常,同原始异常一起抛出一个新异常(带有附加信息),称为链式异常。

    try{
        p1();
    }
    catch(Exception ex){
        throw new Exception(ex);	//在捕获到异常后,带着这个异常抛出一个新异常
        						  //若输出异常信息,会先显示该方法抛出的异常,再显示p1产生的异常
    }
    

    1. 捕获异常

    ​ 在使用中,将可能产生异常的语句放到try里面,若产生异常则会跳过剩下的语句,执行相应的catch部分的语句。

    **注意:**捕获多个异常时,若父类的catch块在子类之前,则会导致编译错误。如下面,若ex1是ex2的父类则会出错。

try {
    statements;	//可能产生异常的语句放入try里面
}
catch (Exception1 ex1){
    handle for ex1;	//对第一个异常进行处理
}
catch (Exception2 ex2){
    handle for ex2;	//对第二个异常进行处理
}
  1. “上级”(调用者)对必检异常的处理:

    ​ 若方法中声明了一个必检异常,则调用者必须在try-catch语句中执行,或者在调用者方法头中声明异常(即再把异常交给它的上级)。例如:若p2()可能会抛出一个必检异常(以IOException为例),方法p1()调用p2,则应该如下处理:

    //捕获p2 的异常
    void p1(){
        try{
            p2();
        }
        catch(IOException ex){
            ...
        }
    }
    //抛出p2的异常
    void p1() throws IOException(){
        p2();
        ...
    }
    

5. finally语句

​ 若希望无论是否出现异常,都执行某些代码,则使用finally。(例如各种连接的关闭)

  1. 使用finally时可以省略catch块

  2. 即使在到达finally前有return语句,依旧会执行finally的代码


6. 一些注意事项

1. 捕获异常时,尽量不要捕获通用异常,如`catch(Exception e)`,应该捕获特定异常。否则可能会捕获到意想不到的异常,而且也会令他人不易理解自己的代码。
2. 对于捕获到的异常不要忽略
3. 记住“Throw early catch late”(早点抛出异常延迟抓取异常)原则,这个原则就是说,应该在异常出现时就将其抛出,抓取应该在能够获取足够信息的时候。简单来说,底层的方法应该更多的抛出异常,异常应该更多的在顶层代码中抓取处理。
4. 异常处理会花费较大的时间和资源,*不要用异常处理来做简单的逻辑测试*。如非必要,勿用异常

7. 复习题

1. throw、throws区别
2. 必检异常和免检异常区别
3. NoClassDefFoundError 和 ClassNoFoundException区别

*PS:欢迎关注我的公众号:赔我板栗 *

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值