Java基础之----异常处理(1.7以上)

什么是异常

异常是在程序执行过程中发生的,中断程序正常执行流程的事件.Exception是exceptional event的简称java编程语言用异常来处理错误和其他异常事件。

处理过程 当在一个方法执行过程中发生一个异常,这个方法会创建一个异常对象,并把发这个对象传递给运行时系统,这个过程叫抛出异常,这个异常对象包含异常的类型以及异常发生时,程序的状态。

运行时系统收到这个异常对象之后,就会去寻找异常处理器。系统会沿着方法调用的反方向,去寻找异常处理器,当找到合适的异常处理器之后,就将这个异常交给异常处理器处理,寻找异常处理器的过程叫做捕获异常。

如果系统没有找到异常处理器,那么程序就会终止。否则,会执行异常处理器的逻辑,当异常处理完毕后,会执行异常处理器之后的代码。

捕获或声明规范

合法的Java程序必须遵守catch和声明规范,也就是可能产生异常的必须被采用以下两种方式的一种包裹: * 要么是try{}catch{}块 * 要么是一个用throws声明的方法 * 这就是捕获或者声明规范。Java将所有异常分为三类:受检查异常、运行时异常和Error,其中,运行时异常和Error有称为不受检查异常。只有受检查异常必须遵守这个原则。如果不遵守这个规则,那么程序将不能通过编译。不受检查异常则不然,它会通过编译,但是程序如果在运行中出错,则会停止程序的执行

异常的分类:

异常可以分为以下三类

受检查异常 这种异常是程序需要预料并且恢复的异常条件

Error 这种异常是程序之外的异常条件,是程序无法意料和恢复的。应用程序可以捕获这类异常,用以通知用户,或者打印相应的log.在异常体系里,Error是所有Error及其子类。它可以不受catch和声明规范的制约。

运行时异常 这类异常是程序之内的异常,通常是由于程序里的逻辑错误或者不正确使用API导致的,这类异常一般程序无法预料和恢复。通常需要消除这种异常的产生。它是Exction的子类。所有RuntimeException及其子类都是运行时异常。

几种常见的运行时异常: ArithmeticException,ArrayStoreException,BufferOverflowException,BufferUnderflowException,IndexOutOfBoundsException,NegativeArraySizeException,NullPointerException

Error和运行时异常统称不受检查异常,这两种异常不受捕获或声明要求的约束。但是,不受检查异常是可以被捕获处理的。

捕获和处理异常

try{

}catch(Exception e){


}finally{

}

try用来包裹可能出现异常的代码块

catch用来处理异常,从Java7开始,一个catch可以捕获多个异常,可以采用以下形式声明:

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

但需要注意的是,当采用这种方式声明的时候,ex默认是一个final类型的。

当异常产生时,运行时系统会将产生的异常类型和catch语句的异常类型比较,找到第一个类型和异常类型匹配catch块便执行异常处理逻辑。所以,catch块的顺序应该按异常类层次结构从下到上的顺序排列

finally块一般在异常处理结束后最后执行,但也不一定一定会被执行。如果在执行try和catch的过程中,jvm退出或者执行这两个块的线程中断或者kill掉了,那么finally是不会被执行 的。这个块通常来执行一些最后的清理工作,用于防止资源泄露

try-with-resources

resources:在程序结束后必须关闭的对象,否则会造成内存泄露。这些对象要么实现了java.lang.AutoCloseable,要么实现了java.lang.Closeable,

try-with-resources是用来声明一个或多个资源对象的,采用这种方式声明的资源对象,不论是否出现异常,在执行完毕后,资源对象会自动关闭。但是,在使用try-with-resources时,如果try-with-resources里在关闭资源时产生异常,此时,如果try块里也产生异常,那么try-with-resources里产生的异常将被抑制。

声明方法抛出异常

如果一个方法在执行过程中可能抛出受检查的异常,这是我们有两种解决方式,第一种,如果我们知道该如何处理该异常,可以直接捕获并处理异常;第二种,如果我们不知道该如何处理,那么我们可以交给方法调用栈的上游的其他方法处理,这时,我们只需要为该方法添加抛出异常的声明即可。如果不捕获也不声明抛出,那么,代码是无法通过编译的。

受检查异常必须采用以上两者中的一种进行处理,不受检查异常可以不处理,但是最好根据需要,作出合适的处理

抛出异常

任何代码都可以抛出异常,你自己的代码、第三方人员写的代码、Java的运行时都可以抛出异常,不管是哪里抛出异常,都是使用throw语句。

Java的异常处理机制定义了一系列的异常类,他们都之间或间接继承自Throwable。在开发过程中,我们可以使用系统定义的异常类,同时也可以自己定义自己的异常类。

使用throw抛出不受检查异常的对象,不需要使用throws声明,但是,如果是抛出受检查异常对象,那么,必须使用throws关键字声明。这里,大家或许会有疑惑:在写代码的时候,没有使用throw关键字抛出对象,为什么还是需要使用throws关键字声明?那是因为,我们调用的方法里使用了throw抛出受检查异常。

异常类图

可以看出,Java提供的异常类都是直接或间接继承自Throwable,其中,Exception有一个子类RuntimeException,Error和RuntimeException及其子类,统称为不受检查异常,这种异常在编译的时候不受检查。其他的异常叫受检查异常,在编译的时候,编译器会检查是否可能发生异常并且提供了异常处理的方法,如果没有,则无法通过编译。

其中,

Error是程序外部发生的异常,主要是一些外部因素造成的,与程序本身无关,通常不需要处理;

RuntimeException是由于不正确的使用API或者程序自己身的逻辑错误造成的,通常需要通过修正程序代码来解决;

Exception通常是程序里面产生的异常,程序员需要捕获并处理异常,是程序从异常中恢复过来。通常处理的就是这类异常。

## 链接异常处理 ##

在我们处理异常的时候,会碰到这样的一个情形:一个异常引发另外一个异常,这个时候就可以考虑链接异常处理。使用很简单:

Throwable getCause()
Throwable initCause(Throwable)
Throwable(String, Throwable)
Throwable(Throwable)

Java的Throwable给我们提供了上面这些方法,我们可以在抛出另外一个异常的时候,利用已有的异常,作为新异常产生的原因初始化新产生的异常,这就是链接异常处理。

自定义异常:

只需要继承Throwable及其子类即可,通常情况下是继承Exception。继承自Error和RuntimeException的情况很少见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值