try、catch、finally、return执行顺序超详解析与throw与throws区别

news/2024/10/10 23:08:36/

try、catch、finally、return执行顺序超详解析(针对面试题)

有关try、catch、finally和return执行顺序的题目在面试题中可谓是频频出现。总结一下此类问题几种情况。

写在前面
不管try中是否出现异常,finally块中的代码都会执行;
当try和catch中有return时,finally依然会执行;
finally是在return语句执行之后,返回之前执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以如果finally中没有return,即使对数据有操作也不会影响返回值,即如果finally中没有return,函数返回值是在finally执行前就已经确定了;
finally中如果包含return,那么程序将在这里返回,而不是try或catch中的return返回,返回值就不是try或catch中保存的返回值了。
注:

finally修改的基本类型是不影响 返回结果的。(传值)
修改list,map,自定义类等引用类型时,是影响返回结果的。(传址的输出是

public class Test{public int add(int a,int b){try{return a+b;}catch(Exception e){System.out.println("catch语句块")     }finally{System.out.println("finally语句块")  }return 0;}   public static void main(String argv[]){Test test=new Test();System.out.println("和是:"+test.add(9,34));  }
}

输出是

finally语句块 和是:43

至于为什么不是:和是 finally块43的原因:

System.out.println(“和是:”+test.add(9,34)); 这是进行字符串拼接是一个整体,所以首先是进入add方法,进去之后先不运算result,而是输出finally块。finally语句块,这句话先打印到控制台中。打印完后返回来执行try中的return得到43,此时再将结果与和是:拼接,输出和是:43.所以最终输出finally语句块 和是:43。

3、try{} catch(){return;} finally{} return;
程序先执行try,如果遇到异常执行catch块,最终都会执行finally中的代码块;

有异常:
执行catch中的语句和return中的表达式运算,但不返回
执行finally语句中全部代码,
最后执行catch块中return返回。 finally块后的return语句不再执行。
无异常:执行完try再finally再return…

有异常


public class Test04 {public static void main(String[] args) {System.out.println(test());}private static int test() {int temp = 1;try {System.out.println(temp);int i=1/0;} catch (Exception e) {System.out.println(temp);return ++temp;} finally {++temp;System.out.println(temp);}return temp;}
}

输出:1132

先执行try中的打印temp=1;有异常,执行catch中的打印,然后执行return中的表达式运算,此时temp=2,并将结果保存在临时栈中,但不返回;执行finally中的语句,temp++,此时temp更新为3,同时打印,但因为finally中的操作不是return语句,所以不会去临时栈中的值,此时临时栈中的值仍然是2。finally中的执行完后,执行catch中的返回,即2。
无异常


public class Test04 {public static void main(String[] args) {System.out.println(test());}private static int test() {int temp = 1;try {System.out.println(temp);} catch (Exception e) {System.out.println(temp);return ++temp;} finally {++temp;System.out.println(temp);}return ++temp;}
}

输出:123

4、try{ return; }catch(){} finally{return;}
执行try块中的代码,和return语句(包括return语句中的表达式运算),但不返回(try中return的表达式运算的结果放在临时栈);
再执行finally块,
执行finally块(和return中的表达式运算,并更新临时栈中的值),从这里返回。
此时finally块的return值,就是代码执行完后的值

5、try{} catch(){return;}finally{return;}
执行try中的语句块,
有无异常
有异常:程序执行catch块中return语句(包括return语句中的表达式运算,,并将结果保存到临时栈),但不返回;
无异常:直接执行下面的
再执行finally块,
执行finally块return中的表达式运算,并更新临时栈中的值,并从这里返回。

无异常:


public class Test04 {public static void main(String[] args) {System.out.println(test());}private static int test() {int temp = 1;try {System.out.println(temp);} catch (Exception e) {System.out.println(temp);return ++temp;} finally {System.out.println(temp);return ++temp;}}
}

输出:112

有异常


public class Test04 {public static void main(String[] args) {System.out.println(test());}private static int test() {int temp = 1;try {System.out.println(temp);int i=1/0;} catch (Exception e) {System.out.println(temp);return ++temp;} finally {System.out.println(temp);return ++temp;}}
}

输出:1123

6、try{ return;}catch(){return;} finally{return;}
程序执行try块中return语句(包括return语句中的表达式运算),但不返回;

有异常:
执行catch块中的语句和rreturn语句中的表达式运算,但不返回,结果保存在临时栈;
再执行finally块
执行finally块,有return,更新临时栈的值,并从这里返回。
无异常:
直接执行finally块
执行finally块,有return,更新临时栈的值,并从这里返回。

无异常:

package com.jc;public class Test04 {public static void main(String[] args) {System.out.println(test());}private static int test() {int temp = 1;try {System.out.println(temp);
//      int i=1/0;return ++temp;} catch (Exception e) {System.out.println(temp);return ++temp;} finally {System.out.println(temp);return ++temp;}}
}

输出:123

有异常

package com.jc;public class Test04 {public static void main(String[] args) {System.out.println(test());}private static int test() {int temp = 1;try {System.out.println(temp);int i=1/0;return ++temp;} catch (Exception e) {System.out.println(temp);return ++temp;} finally {System.out.println(temp);return ++temp;}}
}

输出:1123

7、try{ return;}catch(){return;} finally{其他}
程序执行try块中return语句(包括return语句中的表达式运算),但不返回;

有异常:
执行catch块中return语句(包括return语句中的表达式运算),但不返回;
再执行finally块
无异常:
再执行finally块
执行finally块,有return,从这里返回。

public class Test {public static void main(String[] args) {System.out.println(test());}private static int test() {int temp = 1;try {System.out.println(temp);return ++temp;} catch (Exception e) {System.out.println(temp);return ++temp;} finally {++temp;System.out.println(temp);}}
}

输出结果为132

执行顺序为:

输出try里面的初始temp:1;
temp=2;
保存return里面temp的值:2;
执行finally的语句temp:3,输出temp:3;
返回try中的return语句,返回存在里面的temp的值:2;
输出temp:2。
finally代码块在return中间执行。return的值会被放入临时栈,然后执行finally代码块,如果finally中有return,会刷新临时栈的值,方法结束返回临时栈中的值。

最终结论:
任何执行try 或者catch中的return语句之后,在返回之前,如果finally存在的话,都会先执行finally语句,
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。
不管有没有异常,finally代码块(包括finally中return语句中的表达式运算)都会在return之前执行
多个return(中的表达式运算)是按顺序执行的,多个return执行了一个之后,后面的return就不会执行。不管return是在try、catch、finally还是之外。

throw与throws区别

共同点

两者在抛出异常时,抛出异常的方法并不负责处理,顾名思义,只管抛出,由调用者负责处理。

区别

(1)throws用于方法头,表示的只是异常的申明,而throw用于方法内部,抛出的是异常对象

 

(2)throws可以一次性抛出多个异常,而throw只能一个
(3)throws抛出异常时,它的上级(调用者)也要申明抛出异常或者捕获,不然编译报错。而throw的话,可以不申明或不捕获(这是非常不负责任的方式)但编译器不会报错。

总结
实际开发中,可以根据实际需求自定义异常,具体实现方式可以通过继承Exception类来进行实现。


http://www.ppmy.cn/news/1537167.html

相关文章

NVP的含义?如何理解其在AEM|FLUKE线缆认证测试中的意义?不同的NVP会出现怎样的结果?

在AEM|FLUKE铜缆认证测试中,有很多朋友对NVP设置有疑问,不知道应该怎么去设置它,并很好的应用它,那我们基于此,做一个简单的分析。 什么是NVP? NVP是Nominal Velocity of Propagation的缩写?简单直接译过…

论文阅读——联邦忘却学习研究综述

文章基本信息 作者: 王鹏飞魏宗正周东生宋威肖蕴明孙庚于硕张强 机构: 大连理工大学计算机科学与技术学院大连理工大学社会计算与认知智能教育部重点实验室大连大学先进设计与智能计算教育部重点实验室美国西北大学计算机科学系吉林大学计算机科学与…

AI在医学领域:Arges框架在溃疡性结肠炎上的应用

溃疡性结肠炎(UC)是一种慢性炎症性肠病(IBD),在全球大约影响着500万人,导致肠道炎症和溃疡。在UC的临床试验中,通常通过内窥镜视频来评估结肠疾病的严重程度,并使用如Mayo内窥镜下分…

React常见优化问题

在React开发中,性能优化是一个重要且持续的过程,旨在提升应用的响应速度和用户体验。以下是一些常见的React优化问题详解,并附上相应的代码示例。 1. 避免不必要的组件渲染 React组件的渲染是由其props或state的变化触发的。但是,…

古典舞在线交流:SpringBoot平台实现与优化

第一章 绪论 1.1研究背景 在当今的社会,可以说是信息技术的发展时代,在社会的方方面面无不涉及到各种信息的处理。信息是人们对客观世界的具体描述,是人们进行交流与联系的重要途径。人类社会就处在一个对信息进行有效合理的加工中。它将促进…

Unite Shanghai 2024 技术专场 | Unity 6及未来规划:Unity引擎和服务路线图

在 2024 年 7 月 24 日的 Unite Shanghai 2024 技术专场演讲中,Unity 高级技术产品经理 Jeff Riesenmy 带来演讲 Unity 6 and Beyond: A Roadmap of Unity Engine and Services。作为本次 Unite 首场专题演讲,他介绍了 Unity 引擎的最新进展及其配套的工…

C语言之扫雷小游戏(完整代码版)

说起扫雷游戏,这应该是很多人童年的回忆吧,中小学电脑课最常玩的必有扫雷游戏,那么大家知道它是如何开发出来的吗,扫雷游戏背后的原理是什么呢?今天就让我们一探究竟! 扫雷游戏介绍 如下图,简…

十、kotlin的协程

协程 基本概念定义组成挂起和恢复结构化并发协程构建器作用域构建器挂起函数阻塞与非阻塞runBlocking全局协程像守护线程 Job的生命周期 常用函数延时和等待启动和取消启动取消 暂停 协程启动调度器启动方式启动模式线程上下文继承的定义继承的公式 协程取消与超时取消挂起点取…