我们在编写运行过程中常见的可避免不可避免的异常报错该怎么处理?今天就具体告诉大家如何处理Java异常。
Java的异常处理本质上时抛出异常和捕获异常。
抛出异常指的是如果程序中出现了异常,没有办法将具体的异常打印出来,不做任何处理。通俗来讲就是当前环境下无法获得必要的信息来解决问题,就只能从当前环境中跳出并把问题提交给上一级环境。抛出异常后会发生什么呢?
捕获异常指的是如果程序中出现了异常,就能够详细的打印是什么原因导致了异常并且能够做出相应的处理,能够显示详细的Log。
如果代码时抛出异常的方式,在运行时出现异常,并且打印的Log不明显,可以改用try/catch方式来捕获异常,打印出详细的信息。
对于运行时异常、错误和检查异常,Java技术所要求的异常处理方式都有所不同。具体哪些属于运行时异常,哪些属于错误,哪些属于检查异常,软妹昨天已经详细说明过了。
由于运行时异常及其子类的不可查性,为了更合理、更容易地实现应用程序,Java规定,运行时异常将由Java运行时系统自动抛出,允许应用程序忽略运行时异常。
对于方法运行中出现的错误,当运行方法不预捕捉时,Java允许该方法不做任何抛出声明。而对于所有的检查异常,Java规定当一个方法选择不捕捉检查异常时,就必须声明将抛出异常。
Java异常处理主要是五个关键词,分别是:try、catch、finally、throw、throws。
关键词try后的一堆大括号将一块可能发生异常的代码(监控区域)包起来,。创建异常对象,将异常抛出监控区域之外,有Java运行时系统负责寻找匹配的catch子句来捕获异常。若有一个catch语句匹配到了,则执行该catch块中的异常处理代码,就不在尝试匹配其他catch块了。
很多情况下,由单个的代码段可能引起多个异常。处理这种情况,就需要定义两个或多个的catch子句,每个子句捕获一种类型的异常,当异常被引发时,每个catch子句被依次检查,第一个匹配异常类型的子句执行,当一个catch子句执行以后,其他的子句将被旁路。
try语句也可以被嵌套,一个try语句也可以在另一个try块的内部。每次进入try语句,异常的前后关系都会被推入堆栈。
如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个try语句的catch处理程序将检查是否与之匹配。这个过程将持续到第一个catch语句被匹配成功,或者知道所有的嵌套try语句被检查完毕。如果始终没有catch语句匹配,Java运行时系统将处理这个异常。
当异常发生时,通常方法的执行将做一个陡峭的非线性的转向,它过早的导致方法返回这样的事情发生,从而出现了finally这个设计。
finally创建的代码块在两个try/catch块之间执行。finally块无论有没有异常抛出都会执行。
如果抛出异常,即使没有catch子句匹配,finally也会执行,一个方法将从一个try/catch块返回到调用程序的任何时候,经过一个未捕获的异常或者是一个明确的返回语句,finally子句在方法返回之前仍将执行。这在关闭文件句柄和释放任何在方法开始时被分配的其他资源是很有用。
程序执行完throw语句之后就会立即停止,throw后面的语句不会执行,临近的try块用来检查它是否含有一个与异常类型匹配的catch语句,如果发现了匹配的块,控制转向该语句;如果没有匹配的块,次包围的try块来检查,一直没有匹配的catch块,默认异常处理程序中断程序的执行并且打印堆栈轨迹。
如果一个方法可以导致一个异常但不处理它,它必须指定这种行为以使方法的调用者可以保护它们自己而不发生异常,那么就用到了throws子句。
一个throws子句列举了一个方法可能引发的所有异常类型,这对于出了Error和RuntimeException类是很有必要的,一个方法可以引发的所有其他类型的异常必须在throws子句中声明,否则会导致编译错误。
throws抛出异常的规则:
总结有关异常处理和设计的建议: