们都知道异,常的处理在java语言层面的处理方式是利用 try{}catch()finally{} 范式来处理的。其中:
try代码块,是可能出来异常的代码。
catch代码块,是对try代码块中抛出异常的处理逻辑。
finally代码块,是try和catch代码块执行后,一定会执行的代码逻辑。
正常情况下,代码的执行流程从上到下,先执行try,在执行catch,最后执行finally。然而,很多时候,try中抛出的异常,catch可能无法处理,即使catch可以处理,但是catch在处理的过程中也有可能会产生新的异常。对于后面两种特殊情况的处理,是由finally来完成的,finally会捕获到这些异常,但是由于finally中没有执行这些异常的引用,所以finally对捕获异常的处理,只能将他们抛出去。
异常的处理流程可以参考下图:
上图是目前java中对异常处理的实现方式。java编译器会将finally代码块的内容,复制到try-catch代码块所有正常执行路径和以及异常执行路径的出口处。对于正常执行路径:try代码正常执行的情况和try触发的异常被catch捕获情况,如图中蓝色和黄色的finally代码块。对于异常执行路径:try中抛出了catch无法捕获异常,或者catch中抛出了异常,如图中红色的finally代码块。
第二个异常处理器的from和to指针指向的位置和第一个异常处理器相同,只不过异常类型为any,any表示任何异常,该异常处理器,刚好是第一个异常处理的一个补充,用来处理try代码块抛出的异常不能被catch捕获的情况,对于这种情况,程序执行流程会跳转到target指针指向的27行,也就是finally代码块,然后再将异常throw出去,也就是34行指向的字节码。
第三个异常处理器的from和to指针指向13和19,也就是catch代码块,该异常处理器可以处理任何类型的异常,对catch代码块抛出异常的处理方式是将程序执行流程跳转到27行,和第二个异常处理器的处理逻辑相同。