理论教育 方法调用栈及异常处理

方法调用栈及异常处理

时间:2023-06-19 理论教育 版权反馈
【摘要】:图9-1 Java虚拟机的方法调用栈当方法methodB()调用方法methodA()时,如果方法中的代码块可能抛出异常,有如下两种处理办法。当一个方法正常执行完毕,Java虚拟机会从调用栈中弹出该方法的栈结构,然后继续处理前一个方法。当Java虚拟机追溯到调用栈的最底部的方法,如果仍然没有找到处理该异常的代码块,将调用异常对象的printStackTrace()方法,打印来自方法调用栈的异常信息,随后整个应用程序被终止。

方法调用栈及异常处理

Java虚拟机用方法调用栈(Method Invocation Stack)来跟踪一系列的方法调用过程。该堆栈保存了每个调用方法的本地信息(比如方法的局部变量)。当一个新方法被调用时,Java虚拟机把描述该方法的栈结构置入栈顶,位于栈顶的方法为正在执行的方法。图9-1描述了方法调用栈的结构,图中方法的调用顺序为:main()方法调用methodB()方法,methodB()方法调用methodA()方法。

978-7-111-51616-3-Part03-113.jpg

图9-1 Java虚拟机的方法调用栈

当方法methodB()调用方法methodA()时,如果方法中的代码块可能抛出异常,有如下两种处理办法。

(1)如果当前方法有能力自己解决异常,就在当前方法中通过try-catch语句捕获并处理异常,例如下面的代码。

978-7-111-51616-3-Part03-114.jpg

(2)如果当前方法没能力自己解决异常,就在方法的声明处通过throws语句声明抛出异常,例如下面的代码。

978-7-111-51616-3-Part03-115.jpg

当一个方法正常执行完毕,Java虚拟机会从调用栈中弹出该方法的栈结构,然后继续处理前一个方法。如果在执行方法的过程中抛出异常,Java虚拟机必须找到能捕获该异常的catch代码块。它首先察看当前方法是否存在这样的catch代码块,如果存在,就执行该catch代码块;否则,Java虚拟机会从调用栈中弹出该方法的栈结构,继续到前一个方法中查找合适的catch代码块。

例如,当方法methodA()抛出SpecialException异常时,如果在该方法中提供了捕获SpecialException的catch代码块,就执行这个异常处理代码块。如果方法methodA()未捕获该异常,而是采用第二种方式声明抛出SpecialException,那么Java虚拟机的处理流程将退回到上层调用方法methodB(),再察看方法methodB()中有没有捕获SpecialException。如果在方法methodB()中存在捕获该异常的catch代码块,就执行这个catch代码块,此时定义方法methodB()的代码如下。

978-7-111-51616-3-Part03-116.jpg(www.daowen.com)

由此可见,在回溯过程中,如果Java虚拟机在某个方法中找到了处理该异常的代码块,则该方法的栈结构将成为栈顶元素,程序流程将转到该方法的异常处理代码部分继续执行。

如果方法methodB()也没有捕获SpecialException,而是声明抛出该异常,那么Java虚拟机的处理流程将退回到main()方法,此时定义方法methodB()的代码如下。

978-7-111-51616-3-Part03-117.jpg

当Java虚拟机追溯到调用栈的最底部的方法,如果仍然没有找到处理该异常的代码块,将调用异常对象的printStackTrace()方法,打印来自方法调用栈的异常信息,随后整个应用程序被终止。例如运行如下代码后会打印输出如下异常信息。

978-7-111-51616-3-Part03-118.jpg

会打印输出如下异常信息。

978-7-111-51616-3-Part03-119.jpg

在上述代码中,类SpecialException表示某一种异常,如下代码是它的源程序

978-7-111-51616-3-Part03-120.jpg

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈