Java异常处理机制(基础知识)

        Java语言提供了相对完善的异常处理机制。注意,这里的异常实际上包含了后面要说的“错误”和“异常”,即Error和Exception。

一、Java异常分类

错误和异常

        在Java中,所有的错误和异常有一个共同的祖先 Throwable类,这意味着这些错误和异常可以被捕获(catch)和抛出(throw)。Throwable的两个重要子类:Error(错误)和Exception(异常),此二者是有区别的。

Error:程序无法处理的、比较严重的错误,一般会使得JVM处于非正常且不可恢复的状态,如常见的OutOfMemoryError、StackOverflowError等。Error是不可查的。

Exception:是可以用针对性的代码处理的异常。

一言以蔽之:Error不可被程序本身处理,Exception可以被程序本身处理。

编译时异常和运行时异常

        Exception有两类子类,即RuntimeException和非RuntimeException。RuntimeException即运行时异常,非RuntimeException就是编译时异常。它们又分别可被叫做不受检异常受检异常,此二者是有区别的。

编译时异常(受检异常):编译器要求必须写相应代码去处理此类异常,否则不能通过编译。Java把一些比较常见的异常设计为编译时异常,如FileNotFoundException、ClassNotFoundException和SQLException等。

运行时异常(不受检异常):编译器不强制对这些异常进行处理,当然也可以处理。

 二、Java异常处理机制

Java的异常处理机制为:抛出异常,捕获异常。

抛出异常:抛出异常有两种方式:发生异常时由运行时系统自动抛出、程序员手动抛出(throws xxxException)。对于系统抛出的异常,当一个方法引发异常时,方法会创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行之。对于手动抛出的异常,是程序员通过throw xxxException抛出。 

捕获异常:方法抛出异常之后,运行时系统将转而寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。

对于系统抛出的异常,有两种处理方式:自己处理或者向上抛。

1. 自己处理:try-catch,在catch字句中处理。

2. 向上抛:

        2.1 try-catch,在catch字句中打印日志、生成新的更具可读性的异常对象并throw出去,并在方法名后面声明抛出。 

        2.2 不try-catch,方法名后面声明抛出,这时候抛出去的时原始异常对象。

对于手动抛出的异常,直接在方法名后面声明抛出就行了,其实也可以利用try-catch,但是你自己手动抛出了异常,又自己捕获住,何所为?

三、try-catch

        关键词try后的一对大括号将一块可能发生异常的代码包起来,称为监控区域。Java方法在运行过程中出现异常,则创建异常对象。将异常抛出监控区域之外,由Java运行时系统试图寻找匹配的catch子句以捕获异常。若有匹配的catch子句,则运行其异常处理代码,try-catch语句结束。

  匹配的原则是:如果抛出的异常对象属于catch子句的异常类,或者属于该异常类的子类,则认为生成的异常对象与catch块捕获的异常类型相匹配。

        需要注意的是,一旦某个catch捕获到匹配的异常类型,将进入异常处理代码。一经处理结束,就意味着整个try-catch语句结束。其他的catch子句不再有匹配的机会。

        try-catch后面的代码:如果catch匹配到了try中抛出的异常,且进行了处理、不再抛出、没有产生新的异常,则try-catch结束后还会执行后面的代码。否则,不执行。

四、try-catch-finally

无论是否出现异常,finally子句都会执行。try-catch-finally执行顺序和规则。

        1) 当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;

  2) 当try捕获到异常,catch语句块的异常类型不匹配:此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;

  3) 当try捕获到异常,catch语句块的异常类型匹配:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将进入第一个匹配的catch语句块,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;

        4) 若在try或catch中有return且能被执行到时,在return之前会先执行finally子句。注意,在进入finally之前会先把return后的表达式计算出并保存起来,finally执行之后,回去将此值返回,所以函数返回值是在finally执行前就已确定的。不过,如果finally中也有return,那么程序在finally中就提前返回了,返回值也不会是try或catch中保存的值。故finally中最好不要包含return,否则程序会提前退出。 

参考文章

深入理解Java异常处理机制 - 张顺海 - 博客园

有return的情况下try catch finally的执行顺序 - 张顺海 - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值