从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

    • 我的 Java 学习路线
    • 安装 Java
    • Java 数据类型

    • Java 多版本配置
    • 面向对象

    • Java 核心类

    • IO

    • Java 与时间

    • 异常处理

      • 什么是异常
      • 捕获和抛出异常
      • 深入异常
      • 自定义异常
      • 空指针异常
      • return 和 finally 谁先执行
        • 分类讨论
        • 情况一
        • 情况二
        • 情况三
        • 总结
    • 哈希和加密算法

    • Java8 新特性

    • 网络编程

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaSE
  • 异常处理
2023-03-25
目录

return 和 finally 谁先执行

# return 和 finally 谁先执行

本文聊聊 try 或 catch 块中,如果有了 return,那么是 return 先执行还是 finally 先呢?

# 分类讨论

假设 try 块中有 return 语句,try 语句在返回前,将其他所有的操作执行完,保留好要返回的值,而后转入执行 finally 中的语句。分为以下情况:

  • 情况一:如果 finally 中有 return 语句,则会将 try 中的 return 语句”覆盖“掉,直接执行 finally 中的 return 语句,得到返回值,这样便无法得到 try 之前保留好的返回值。

  • 情况二:如果 finally 中没有 return 语句,也没有改变要返回值,则执行完 finally 中的语句后,会接着执行 try 中的 return 语句,返回之前保留的值。

  • 情况三:如果 finally 中没有 return 语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况:

    • 1)如果 return 的数据是基本数据类型或文本字符串,则在 finally 中对该基本数据的改变不起作用,try 中的 return 语句依然会返回进入 finally 块之前保留的值。
    • 2)如果 return 的数据是引用数据类型,而在 finally 中对该引用的成员变量的改变起作用,因为返回的是引用,引用是没有变的,但引用里面的成员变量被改变了
  • 特殊情况:在 try 里面有 System.exit(0) 这样的语句,System.exit(0) 是终止 Java 虚拟机 JVM 的,连 JVM 都停止了,一切都结束了,也就不存在返回值给调用者的情况

# 情况一

finally 中有 return 语句,会将 try 中的 return 语句”覆盖“。测试代码:

/*  情况一:如果finally中有return语句,则会将try中的return语句”覆盖“掉,
      直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。
   */
  public static int testCase1(){
    int number = 100;
    try{
      System.out.println("testCase1 try语句块执行中... ");
      number += 100;
      return number;
    }catch (Exception e){
      e.printStackTrace();
    }finally {
      System.out.println("testCase1 finally语句块执行中...");
      number = 500;
      return number;
    }
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

执行结果:

 System.out.println("testCase1返回:" + testCase1());  //500
1

# 情况二

如果 finally 中没有 return 语句,也没有改变要返回值,则执行完 finally 中的语句后,会接着执行 try 中的 return 语句。测试代码:

 /**
   *  情况二:如果finally中没有return语句,也没有改变要返回值,
   *  则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。
   * @return
   */
  public static int testCase2(){
    int number = 100;
    try{
      System.out.println("testCase2 try语句块执行中... ");
      number += 100;
      return number;
    }catch (Exception e){
      e.printStackTrace();
    }finally {
      System.out.println("testCase2 finally语句块执行中...");
    }

    return 10;
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

执行结果:

    System.out.println("testCase2返回:" + testCase2());  //200
1

# 情况三

如果 finally 中没有 return 语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况:

  • 1)如果 return 的数据是基本数据类型或文本字符串,则在 finally 中对该基本数据的改变不起作用,try 中的 return 语句依然会返回进入 finally 块之前保留的值。
  • 2)如果 return 的数据是引用数据类型,而在 finally 中对该引用的成员变量的改变起作用,因为返回的是引用,引用是没有变的,但引用里面的成员变量被改变了

# 3.1

/**
   * 情况三:如果finally中没有return语句,但是改变了要返回的值,并且返回的是基本数据类型,则改变不会生效
   * @return
   */
  public static int testCase3(){
    int number = 100;
    try{
      System.out.println("testCase3 try语句块执行中... ");
      number += 100;
      return number;
    }catch (Exception e){
      e.printStackTrace();
    }finally {
      System.out.println("testCase3 finally语句块执行中...");
      number = 500;

    }

    return 10;
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

运行结果:

    System.out.println("testCase3返回:" + testCase3());  //200
1

# 3.2

/**
   * 情况三:如果finally中没有return语句,但是改变了要返回的值,并且返回的是引用数据类型,则改变会生效
   * @return
   */
  public static Num testCase3_2(){
    Num number = new Num();
    try{
      System.out.println("testCase3_2 try语句块执行中... ");
      return number;
    }catch (Exception e){
      e.printStackTrace();
    }finally {
      System.out.println("testCase3_2 finally语句块执行中...");
      number.num = 100;

    }

    return number;
  }


class Num{
  public  int num = 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

运行结果:

    System.out.println("testCase3_2返回:" + testCase3_2().num);  //200
1

# 总结

即使在 try 或 catch 代码块中有 return 语句,也会执行 finally 语句,但是 finally 能否改变返回的值,取决于 return 后的内容是否为引用类型,如果是则引用的成员变量可以发生改变,如果为基本数据类型,则不可发生改变。

参考:

return 和 finally 谁先执行_先 return 还是先 finally_醺泽的博客-CSDN 博客 (opens new window)

try catch 语句中有 return 的各类情况_hello_world_he 的博客-CSDN 博客 (opens new window)

上次更新: 2025/6/3 09:31:54
空指针异常
什么是哈希算法

← 空指针异常 什么是哈希算法→

最近更新
01
学点统计学:轻松识破一本正经的胡说八道
06-05
02
2025 年 5 月记
05-31
03
《贫穷的本质》很棒,但可能不适合你
05-27
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式