Practical Java笔记三:认识异常控制流机制
public class Practical_16_exception { public static void main(String[] args) { System.out.println("Entering Main()"); Practical_16_exception pe = new Practical_16_exception(); try { System.out.println("Calling m1()"); pe.m1(); System.out.println("Returning from call to m1()"); //1 } catch (Exception e) { System.out.println("Caught IOException in main()"); } System.out.println("Entering Main()"); } public void m1() throws IOException{ System.out.println("Entering m1()"); Button b1 = new Button(); try { System.out.println("Calling m2()"); m2(); System.out.println("Returning from call to m2()"); System.out.println("Calling m3()"); m3(true); System.out.println("Returning from call to m3()"); //2 } catch (IOException e) { System.out.println("Caught IOException in m1()...throws"); throw e; //3 }finally{ System.out.println("in finally for m1()"); } System.out.println("Exiting m1()"); //4 } public void m2(){ System.out.println("Entering m2()"); Button b1 = new Button(); try { Vector v = new Vector(5); } catch (IllegalArgumentException e) { System.out.println("Caught IllegalArgumentException in m2()"); //5 throw e; }finally{ System.out.println("in finally for m2()"); } System.out.println("Exiting m2()"); } public void m3(boolean flag) throws IOException{ System.out.println("Entering m3()"); Button b1 = new Button(); try { Button b = new Button(); if(flag) throw new IOException(); } finally{ System.out.println("in finally for m3()"); } System.out.println("Exiting m3()"); //6 } }
这里展现了代码的详细执行轨迹。一旦执行这段代码,首先打印一条消息,
然后进入try区段,再打印一条消息,然后调用m1()。进入m1()之后,打
印一条消息,再进入try区段打印另一条消息,然后调用m2()。
进入m2()之后,先打印一条消息,然后进入try区段,其中并未抛出异常。
于是跳过catch区段,控制流转移到m2()的finally区段。在那里打印一条
消息,并在函数退出(exit)之前打印另一条消息。m2()返回m1()内的调用
点,又打印出两条消息,然后调用m3()。
进入m3()之后,打印一条消息后进入try区段,其中抛出一个异常。离开
这个函数之前会先执行m3()的finally区段,打印一条消息。而后控制流转
移到身为调用端的m1()的catch区段中。这个catch区段先打印一条消息,
并再次抛出异常。在即将离开m1()之前,先执行finally区段,打印一条消
息,然后返回至调用端main()。
此时进入main()的catch区段,打印一条消息。由于异常在此处获得了处理
未被再次抛出,所以这个catch区段结束后,控制流由此继续向前,并在main()末尾处打印一条消息。而后程序结束。
这段执行轨迹显示,一旦程序抛出异常,相应的代码便立即停止执行,控
制流转移到他处。请注意,本例的//1、//2、//4、//5、//6并没有
出现在输出中。
由于程序在//1和//2之前产生了异常,控制流直接转移到函数的catch
区段,因此这两处的代码没来得及执行。//4和//6之所以未被执行,原
因是此前抛出的异常没有被捕获(译注://4之前的异常虽然被捕获了,
但再次被抛出,相当于没有捕获),因此在执行完finally区段后控制流立刻
跳离函数。(如果//3没有再次抛出异常,//4就会被执行)。//5也没有执
行,因为//5之前的try区段并没有抛出任何异常,所以不可能调用//5
所在的那个catch区段。
这说明了当程序在try区段内抛出异常时将会发生的事情:
1.如果同时存在catch区段和finally区段,则控制流会先转移到catch
区段,然后再跳转到finally区段。
2.如果没有catch区段,控制流便转移到finally区段。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述