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

news2024/11/24 16:22:49

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.coloradmin.cn/o/2203172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IPguard与Ping32敏感内容防护能力对比,两款知名防泄密软件对比

在信息安全的新时代,企业面临着日益严重的敏感内容泄露风险。为了保障数据安全,选择合适的防护工具至关重要。IPguard与Ping32作为市场上两款知名的终端管理解决方案,各自具备独特的敏感内容防护能力。本文将对这两者进行深入对比&#xff0c…

kubeadm 搭建k8s 1.28.2版本集群

kubeadm 搭建k8s 1.28.2版本集群 1、kubuadm介绍: kubeadm 是官方社区推出的一个用于快速部署kubernetes 集群的工具,这个工具能通过两条指令完成一个kubernetes 集群的部署: 创建一个Master 节点kubeadm init将Node 节点加入到当前集群中…

minio集群部署

最近接触到minio, 将本地集群部署,分别在ubuntu、centos stream9上进行了搭建,目前看里面的小坑不小,记录以下教程,以备忘、以供他人借鉴。 #### 准备 1、因新版本的minio要求,集群部署必须使用挂载非 roo…

Java基础:字符串详解

1 深入解读String类源码 1.1 String类的声明 public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence { }String类是final的&#xff0c;意味着它不能被子类继承&#xff1b;String 类实现了Serializable接口&#xff0c;意味着…

没人告诉你的职场人情世故

看到前同事在群里分享的新年开工遭遇&#xff0c;真是让人感同身受。 第一天就遇到挫折&#xff0c;因为工作做得太快、太早交付&#xff0c;结果反被领导批评&#xff0c;还得重做&#xff0c;头大如斗。这不就提醒我们得时时刻刻记着职场里的那些不成文的规矩吗&#xff1f;…

Hunuan-DiT代码阅读

一 整体架构 该模型是以SD为基础的文生图模型&#xff0c;具体扩散模型原理参考https://zhouyifan.net/2023/07/07/20230330-diffusion-model/&#xff0c;代码地址https://github.com/Tencent/HunyuanDiT&#xff0c;这里介绍 Full-parameter Training 二 输入数据处理 这里…

一、Spring入门

文章目录 1. 课程内容介绍2. Spring5 框架概述3. Spring5 入门案例 1. 课程内容介绍 2. Spring5 框架概述 3. Spring5 入门案例

Java反射专题

目录 一.反射机制 1.Java Reflection 2.反射相关的主要类 3.反射的优缺点 4.反射调用优化—关闭访问检查 二.Class类 1.基本介绍 2.常用方法 3.获取Class对象的方式 4.那些类型有Class对象 三.类加载 1.介绍 2.类加载时机 3.类加载各阶段 四.获取类结构的信息 1…

25.第二阶段x86游戏实战2-背包属性补充

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

机器学习项目——运用机器学习洞察青年消费趋势

1. 项目背景 在21世纪的第三个十年&#xff0c;全球经济和技术的飞速发展正深刻影响着各个领域&#xff0c;尤其是青年消费市场。随着数字化进程的加速&#xff0c;尤其是移动互联网的广泛普及&#xff0c;青年的消费行为和生活方式发生了前所未有的转变。 然而&#xff0c;面对…

开源版GPT-4o来了!互腾讯引领风潮,开源VITA多模态大模型,开启自然人机交互新纪元[文末领福利]

目录 总览 VITA 模型的详细介绍 2.1 LLM 指令微调 2.2 多模态对齐 2.2.1 视觉模态 2.3 音频模态 多模态指令微调 3.1 训练数据 3.1.1 训练过程 模型部署&#xff1a;双工策略 4.1 非唤醒交互 4.2 音频中断交互 评估 5.1 语言表现 5.2 音频表现 5.3 多模态表现 …

离散微分几何中的网格(Meshes)

https://zhuanlan.zhihu.com/p/893338073 一、引言 ![](https://img-blog.csdnimg.cn/img_convert/c5e06e652822e0003cf6be91d26436b7.png) 在离散微分几何的广袤领域中&#xff0c;网格&#xff08;Meshes&#xff09;作为一个核心概念&#xff0c;犹如一座桥梁&#xff0c;…

小灰:从0到年入100万+,从程序员到自由职业者他经历了什么?

这是开发者说的第20期&#xff0c;这次给大家带来的畅销书《漫画算法》作者、自媒体创作者程序员小灰。 小灰做自媒体的时间已经有8年了&#xff0c;目前在全网有60w粉丝&#xff0c;同时《漫画算法》系列和《漫画ChatGPT》的书籍&#xff0c;在全网卖了12万册&#xff0c;靠写…

rocky9 samba共享

1. 安装samba服务&#xff0c;设置开机自启。 2. 创建四个用户user1&#xff0c;user2&#xff0c;sale1&#xff0c;manager&#xff0c;user1&#xff0c;user2属于finance组&#xff0c;sale1属于sales组&#xff0c;manager属于manager组。 3. 建立共享目录/opt/finance_…

模版进阶 非类型模版参数

一.模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中可将该参数当成常量来使用。 #i…

打印1000年到2000年之间的闰年

我们要打印1000年到2000年之间的闰年&#xff0c;首先我们先输出1000年到2000年之间的所有的年份&#xff0c;同时我们将闰年的判断方法输入到其中 闰年需要满足下列两个条件的其中之一&#xff1a; 1.能被4整除但不能被100整除 2.能被400整除 打印1000年到2000年之间的闰年…

PCL 贪婪三角投影三角化

目录 一、概述二、代码三、结果 一、概述 PCL中贪婪三角投影三角化的简单使用案例 二、代码 greedy_projection.cpp #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/search/kdtree.h> // for KdTree #include <pcl/features/…

【软件系统架构设计师-案例-1】架构风格

1. 请用200字以内说明系统可靠性的定义及包含的4个子特性&#xff0c;并简要指出提高系统可靠性一般采用哪些技术&#xff1f; &#xff08;1&#xff09;可靠性定义&#xff1a;系统在规定的时间或环境条件下&#xff0c;完成规定功能的能力&#xff0c;就是系统无故障运行的…

【AD速成】半小时入门AltiumDesigner(速通基础)

一.创建工程 1.工程 文件->新的->项目 PCB选择<Default>Project Name填入自己的工程名称Folder选择工程保存的路径 创建后如图&#xff1a; 这里的.prjPcb的文件即为AD的工程文件。 如果没有Project栏可以在视图->面板->Projects中勾选Projects CtrlS保存工…

Java学习-JVM调优

目录 1. JDK工具包 1.1 jps 1.2 jstat 1.3 jinfo 1.4 jmap 1.5 jhat 1.6 jstack 1.7 VisualVM 2. 第三方工具 2.1 GCEasy 2.2 MAT 2.3 Arthas 3. JVM参数 3.1 标准参数 3.2 非标准参数 3.3 不稳定参数 4. 调优 4.1 什么时候调优 4.2 调优调什么 4.3 调优原…