Java-异常

151 阅读4分钟

一、异常

异常机制可以使程序中的异常处理代码和正常业务代码分离。保证程序代码更加优雅,并可以提高程序的健壮性。

java异常机制主要依赖try catch finally throw throws五个关键字:
try -> 放置可能引发异常的代码
catch -> 对应异常类型和一个代码块 用于表明该catch用于处理这种类型的代码块
finally -> 用于回收在try块里打开的物理资源(数据库连接、网络连接、磁盘文件)
throws -> 主要在方法签名中使用,用于声明该方法可能抛出的异常
throw -> 抛出一个具体的异常对象

通常情况下,不要在finally块中使用return/throw等导致终止的语句,否则会导致try catch块中的return throw失效。
{ java程序执行try catch的终止语句,系统不会结束该方法,而是去查找是否包含finally块,如果没有则立即执行return throw语句,方法终止;如果有系统立即开始执行finally块-只有finally块执行完成后,系统才会跳回来执行try catch中的return throw语句;如果finally块有导致方法终止的语句,系统则不会跳转回去执行try catch的代码。}

分类: image.png

异常对象都是派生于Throwable类,分为Error和Exception

Error类层次结构描述了java运行时系统的内部错误和资源耗尽错误。

Exception分为RuntimeException(由于程序错误导致)和其他异常(程序本身无问题,I/O异常)

Error+RuntimeException 非受检异常 其他都是受检异常

区分受检还是非受检异常:受检异常,java强制要求处理,否则会有编译错误;非受检异常则没这个要求

二、初始异常

    异常若没处理,java就会启用默认处理机制,打印异常堆栈并退出程序。

    异常处理机制会从当前函数开始查找谁捕获了此异常,没有就查看上一层指导主函数,如果主函数没处理就只用默认机制

    --异常相对于return的一种退出机制,可以由系统触发,也可以由程序通过throw语句触发。可以通过try/catch捕获处理

三、异常处理

3.1 catch匹配

    try{

        //可能触发异常的代码

    }catch(NumberFormatException e){

        System.out.println("not valid number");

    }catch(RuntimeException e){

        System.out.println("runtime exception "+e.getMessage());

    }catch(Exception e){

        e.printStackTrace();

    }

    异常处理机制根据抛出的异常类型找到第一个匹配的catch块,执行catch内的代码,其他catch块不执行,如果没找到则会继续到上层方法查找。

    [抛出的类型是catch中声明异常的子类也算匹配,所以需要将具体的子类放在前面,如果Exception放在前面,则其他更具体的catch将得不到执行]

3.2 重新throw

    在catch块内处理完后,可以重新抛出异常,异常可以是原来的,也可以是新建的.

    重新抛出异常,就会把当前Exception作为cause传递给新建的异常,形成异常链,捕获到新的异常的代码可以通过getCause()获取到原始异常。

3.3 finally

    try{

    //可能抛出异常

    }catch(Exception e){

        //捕获异常

    }finally{

        //不管有无异常都执行

    }

    

    finally内的代码不管有无异常发生,都会执行。具体来说:

    *如果没有异常发生,在try内的代码执行结束后执行。

    *如果有异常发生且被catch捕获,在catch内的代码执行结束后执行

    *如果有异常发生但没被捕获,则在异常被抛给上层之前执行。

    *一般用户释放资源(数据库连接 文件流等)

    

    --如果在try或者catch语句内有return语句,则return语句在finally语句执行结束后才执行,但finally并不能改变返回值

    --如果在finally中也有return语句,try和catch内的return会丢失,实际会返回finally中的返回值

    --为避免混淆,应该避免在finally中使用return语句或者抛出异常

3.4 throws

    关键字throws,用于声明一个方法可能抛出的异常

    public void test() throws AppException,SQLException {

        //....

    }

    checked exception必须出现在throws语句中,调用者必须处理,Java编译器会强制这一点,而RuntimeException则没有这个要求.

    RuntimeException(unchecked)表示编程的逻辑错误,编程时应该检查以避免这些错误;Checked exception表示程序本身没问题,但由于I/O、网络、数据库等其他不可预测的错误导致的异常,调用者应该进行适当处理。