深入虚拟机笔记之finally子句

第18章 finally子句

    微型子例程:字节码中的finally子句在方法内部的表现很想“微型子例程”。java虚拟机在每个try语句块和与其相关的catch子句的结尾都会调用finally子句的子例程,finally子句结束后(这里结束指的是finally子句中的最后一条语句正常执行完毕,没有抛出异常,或执行return、continue、break等情况),隶属于这个finally子句的微型子例程执行“返回”操作;程序在第一次调用微型子例程的地方继续执行后面的语句。

    jsr指令是使java虚拟机跳转到微型子例程的操作码。jsr使用一个双字节长度的操作数,这个操作数指出从jsr指令到微型子例程开始处的16位带符号的偏移量。当java虚拟机遇到jsr指令时,它会把返回地址压入栈,然后从finally微型子例程的开始处继续执行。返回地址是紧接在jsr操作码和操作数后面的字节码地址(偏移量或本地指针),该地址的类型为returnAddress。

    微型子例程执行完毕后,将调用ret指令,ret指令执行从子例程中返回的操作,ret指令只有一个操作数,这个操作数是一个存储返回地址的局部变量的索引。

    jsr指令并不会调用java方法,它只能跳转到相同方法的不同操作码处;同样,ret指令也不能令java方法返回,它只能使虚拟机调回相同方法中调用jsr操作码和它的操作数之后的位置。

    在每一个finally微型子例程的开始处,返回地址都会从栈顶弹出,并且存储在局部变量中,ret指令将会从这个局部变量中取出返回地址。这样做是由于,finally微型子例程本身会抛出异常或者含有return、break、continue等语句;由于这些可能性的存在,被jsr指令压入栈的额外返回地址必须立即从栈中移除。当finally子例程通过return、break、continue或者抛出异常退出时,栈中的额外返回地址就不必考虑了。



 

猜你喜欢

转载自jaesonchen.iteye.com/blog/2289786