异常的执行流程

以下验证三个问题:

1.try catch语句抛出异常,finally语句也抛出异常,结果怎样?

2.try catch语句return和finally的执行顺序,先return还是先finally语句?

3.try catch语句和finall语句都return,最后return的是哪一个?

try catch语句抛出异常,finally语句也抛出异常,结果怎样?

有以下关系:

ExceptionA extends Exception

ExceptionB extends ExceptionA

ExceptionC extends ExceptionB

以下代码:

public class Test01 {

	public static void main(String[] args) throws Exception,ExceptionA,ExceptionB{
		try{
			System.out.println("抛ExceptionC异常");
			throw new ExceptionC("ExceptionC");
		}catch(ExceptionB e){
			System.out.println("抛ExceptionB异常");
			throw new ExceptionB("ExceptionB");
		}catch(ExceptionA e){
			System.out.println("抛ExceptionA异常");
			throw new ExceptionA("ExceptionA");
		}finally{
			System.out.println("抛ExceptionFinally异常");
			throw new Exception("ExceptionFinally");
		}
	}
}
输出如下:
抛ExceptionC异常
抛ExceptionB异常
抛ExceptionFinally异常
Exception in thread "main" java.lang.Exception: ExceptionFinally
	at Test01.main(Test01.java:16)

由结果可以知道,虽然第一个catch捕获到try语句的异常,但没有抛出成功,而是抛出了finally的异常,finally里面抛出异常会提前结束程序。

值得注意的是第一个catch捕获到异常后,抛出ExceptionB异常,但没有被第二个catch捕获,因为同一个try只会根据顺序catch一次。

try catch语句return和finally的执行顺序,先return还是先finally语句?

代码如下:

public class Test01 {
	public static void main(String[] args) {
		System.out.println(test3());
	}
	public static int test3(){
		int i=0;
		try{
			i++;
              return i;
		}catch(Exception e){
			i++;
			return i;
		}finally{
			i++;
		}
         return 0;
	}
}
输出:
1

执行顺序:

1) 执行try语句,i=1,将要返回的1先保存,等执行完finally再返回这个值

2)执行finally,i=2,接着执行上面的return语句,将1返回

try catch语句和finall语句都return,最后return的是哪一个?

代码如下:

public class Test01 {
	public static void main(String[] args) {
		System.out.println(test2());
	}
	public static int test2(){
		int i=0;
		try{
			i++;
			return i;
		}catch(Exception e){
			return -1;
		}finally{
			i++;
			return i;
		}
	}
}
输出:
2

执行顺序如下:

1) 执行try语句,i=1,将要返回的1先保存,等执行完finally再返回这个值

2)执行finally,i=2,返回2,此时程序提前结束,上面的1无法被返回

总结

1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return或throw时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

5、finally中最好不要包含throw,否则程序会提前退出,抛出的异常不是try或catch中的抛出的,而是finally抛出的。

时间: 2024-10-10 19:10:24

异常的执行流程的相关文章

JAVA中的异常(异常处理流程、异常处理的缺陷)

异常处理流程 1)首先由try{...}catch(Exception e){ System.out.println(e); e.printStackTrace(); }finally{...}结构 2)当JVM遇到异常时,会产生一个Exception对象 或 继承自Exception的子类的对象. 3)将异常对象向上层(调用它的代码块)抛出,知道碰到一个catch块(作相应处理) 或 一直抛到了最外层(导致程序异常终止).(并停止异常之后的代码的执行,但是finally块中的代码还会执行!换句

ARMv7用户层发生指令异常的处理流程?是否每个进程都有一个APSR的副本?

1.用户层发生指令异常的处理流程? 用户层程序正在执行时,遇到未定义的指令(ARM不是别的指令)或者SWI软件中断指令(产生系统调用),就会产生异常,这里以未定义指令异常为例进行说明: 一旦出现未定义指令异常,CPU会自动做如下操作: (1)未定义模式(ARM其中运行模式的一种)下对应的lr(即R14)寄存器保存当前发生异常的指令下一条指令的地址.例如,在用户态有A B C 三条指令,指令A发生未定义指令异常,则指令B的地址就会由CPU保存到未定义模式下的lr寄存器中,用于异常返回. (2)CP

线程池的执行流程

合理使用线程池能够带来3个好处: 1)降低资源消耗:2)提高响应速度:3)提高线程的可管理性. 那么线程池是如何工作的呢,借用并发编程艺术一书中的话来描述当一个任务提交给线程池之后,线程池会怎么做? 首先,线程池会判断核心线程池里的线程(线程总数是30,则coreSize有可能是10)是否都在执行任务.如果没有比方说当前只有9个线程在工作,则从核心线程池中创建一个新的线程来执行任务.如果当前已经有10个线程在工作了,则进入下一步: 其次,线程池会判断工作队列是否已经满了,如果工作队列没有满,则将

Android中图片加载框架Glide解析2----从源码的角度理解Glide的执行流程

转载地址:http://blog.csdn.net/guolin_blog/article/details/53939176 在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),Glide的基本用法 . 在多数情况下,我们想要在界面上加载并展示一张图片只需要一行代码就能实现,如下所示: Glide.with(this).load(url).into(i

YII框架分析笔记1:YII执行流程

yii整体执行流程直观,具体由以下步骤: 1.程序入口文件index.php加载yii框架引导程序(bootstrap)文件yii.php,加载配置文件以及其他自定义配置. 2.yii.php中Yii类继承了YiiBase,主要封装框架的一些通用方法,比如自动加载.创建组件.核心类路径映射.记录日志以及调试等,YiiBase.php中注册自动加载方法.另外Yii类预留可以自定义一些方法作为扩展. 3.回到index.php,Yii::createWebApplication($config),创

Servlet、Struts2、SpringMVC执行流程

Servlet 有以下四个阶段: 1.加载和实例化 Servlet容器负责加载和实例化Servlet. 当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,创建Servlet实例. 当Servlet容器启动后,它必须要知道所需的Servlet类在什么位置,Servlet容器可以从本地文件系统.远程文件系统或者其他的网络服务中通过类加载器加载Servlet类,成功加载后,容器创建Servlet的实例. 因为容器是通过Java的反射API来创建 Servlet实例,

struts2的执行流程与配置详解

本章主要讲解Struts的执行流程以及Struts的配置以及访问servletApi 全部代码下载: github链接:链接 写文章不易,欢迎大家采我的文章,以及给出有用的评论,当然大家也可以关注一下我的github:多谢: 1.Struts的执行流程: 1.服务器启动时: 加载项目web.xml 创建Struts核心过滤器对象, 执行StrutsPrepareAndExecuteFilter的doFilter 的 init()方法: 在StrutsPrepareAndExecuteFilter

servlet执行流程和生命周期

一.servlet执行流程: 二.生命周期: Servlet的生命周期可以分为四个阶段,即装载类及创建实例阶段.初始化阶段.服务阶段和实例销毁阶段. 1.初始化阶段  调用init()方法 2.响应客户请求阶段.调用service()方法,由service()方法根据提交的方式选择执行doGet()或者doPost()方法 3.终止阶段 调用destroy()方法 1.创建servlet实例: 在默认情况下Servlet实例是在第一个请求到来的时候创建,以后复用.如果有的Servlet需要复杂的

Liberty nova-api HTTP请求执行流程

本博客欢迎转载,但请注明出处 http://blog.csdn.net/ringoshen/article/details/51387038 由于能力与时间有限,文章内容难免错漏,望大家多加指正,相互进步! 0. 前言 这次看了一下nova list命令的执行过程,整个过程可以分为几步:HTTP请求.URLMap分发.过滤.APIRouter到具体执行函数,接下来使用Postman组个包并发送http请求作为开始对各个模块进行跟踪和注解. 1. HTTP请求 OpenStack组件都是通过RES