看几个例子,回顾一下执行顺序

例子1 无异常,finally中的return会导致提前返回

public static String test() {

try {

System.out.println("try");

return "return in try";

} catch(Exception e) {

System.out.println("catch");

return "return in catch";

} finally {

System.out.println("finally");

return "return in finally";

}

}

调用test()的结果:

try

finally

return in finally

例子2 无异常,try中的return会导致提前返回

public static String test() {

try {

System.out.println("try");

return "return in try";

} catch(Exception e) {

System.out.println("catch");

} finally {

System.out.println("finally");

}

return "return in function";

}

调用test()的结果:

try

finally

return in try

例子3 有异常,finally中的return会导致提前返回

public static String test() {

try {

System.out.println("try");

throw new Exception();

} catch(Exception e) {

System.out.println("catch");

return "return in catch";

} finally {

System.out.println("finally");

return "return in finally";

}

}

调用test()的结果:

try

catch

finally

return in finally

例子4 有异常,catch中的return会导致提前返回

public static String test() {

try {

System.out.println("try");

throw new Exception();

} catch(Exception e) {

System.out.println("catch");

return "return in catch";

} finally {

System.out.println("finally");

}

}

调用test()的结果:

try

catch

finally

return in catch

例子4 有异常,不会提前返回

public static String test() {

try {

System.out.println("try");

throw new Exception();

} catch(Exception e) {

System.out.println("catch");

} finally {

System.out.println("finally");

}

return "return in function";

}

调用test()的结果:

try

catch

finally

return in function

小结

上面这几个例子,大多数人已经非常了解。同时也衍生出一些理论,比如不要在finally中return等,不再赘述。

再看几个例子,返回值是否符合你的预期?

例子1

public static int test() {

try {

return 1;

} finally {

return 2;

}

}

返回值:2

说明:与我们上面的例子一致,finally中的return导致提前返回,try中的return1不会被执行。

附编译后的代码:

public static int test() {

try {

boolean var0 = true;

return 2;

} finally {

;

}

}

可以看到编译器做过优化,同时验证了boolean类型在底层是用int实现的,但注意你在源码中直接给int行赋值true或false是不被允许的。

例子2

public static int test() {

int i;

try {

i = 3;

} finally {

i = 5;

}

return i;

}

返回值:5

说明:执行try中的代码后,再执行finally中的代码,最终i被赋值为5,最后返回

附编译后的代码:

public static int test() {

boolean var0 = true;

byte i;

try {

var0 = true;

} finally {

i = 5;

}

return i;

}

同样可以看出,编译器做了一些优化。

例子3

public static int test() {

int i = 1;

try {

i = 3;

return i;

} finally {

i = 5;

}

}

返回值:3

这个例子稍微有点意思,按我们通常的思维,应该还是返回5,毕竟finally中把i赋值为5了嘛,然后由try中的return返回。然而很不幸,返回值是3。

为什么呢?先看一下编译后的代码:

public static int test() {

boolean var0 = true;

byte var1;

try {

int i = 3;

var1 = i;

} finally {

var0 = true;

}

return var1;

}

我们会发现,finally中的代码块不起作用。不知你是否想起一点:Java中是按值传递的,finally中的i只是一个局部变量,finally块执行完毕后,局部变量便不复存在。

接着看例子:

例子4

public static List test() {

List list = new ArrayList<>();

try {

list.add(1);

return list;

} finally {

list.add(2);

}

}

返回:包含1和2两个元素的List对象。

说明:这个例子中,基本类型int被替换为引用类型List,虽然list是按值传递,但它内部的状态可变(体现在这里,就是可以add元素)。扩展:finally只能保证对象本身不可变,但无法保证对象内部状态不可变。

附编译后的代码:

public static List test() {

ArrayList list = new ArrayList();

ArrayList var1;

try {

list.add(1);

var1 = list; // 执行这一步操作后,var1和list指向同一个对象

} finally {

list.add(2);

}

return var1;

}

你现在应该觉得自己理解了,那么再来看两个例子:

例子5

public static int test() {

try {

System.exit(0);

} finally {

return 2;

}

}

该函数没有返回值。原因:jvm提前退出了。

附编译后的代码:

public static int test() {

try {

System.exit(0);

return 2;

} finally {

;

}

}

例子6

public static int test() {

try {

while(true) {

System.out.println("Infinite loop.");

}

} finally {

return 2;

}

}

由于try中的无限循环阻塞,永远执行不到finally中的代码块。

附编译后的代码:

public static int test() {

try {

while(true) {

System.out.println("Infinite loop.");

}

} finally {

;

}

}

小结

为了方便说明,只举了finally代码块的例子,catch代码块是类似的。

总结

执行顺序:

1. try代码块中return前面的部分

2. catch代码块中return前面的部分

3. finally代码块中return前面的部分

4. finally的return 或 catch的return 或 try的return。若前面的return被执行,会导致提前返回,同时后面的return被忽略。

5. 方法的其他部分

变量:

注意Java的按值传递规则

特殊情况:

注意finally不会被执行的情况

参考

java中catch什么意思_你真的理解Java中的try/catch/finally吗?相关推荐

  1. java 虚拟机类型的卸载_《深入理解Java虚拟机》:类加载和初始化(二)

    <深入理解Java虚拟机>:类加载和初始化(二) 在去年看<深入理解Java虚拟机>的时候,写过一篇关于类加载和初始化的博客,最近又在看这一块的知识,发现还是有很多东西没有理解 ...

  2. java 内存溢出的分类_【深入理解Java虚拟机】读后感:JVM内存划分与内存溢出小结...

    扫码关注公众号:Java 技术驿站 发送:vip 将链接复制到本浏览器,永久解锁本站全部文章 [公众号:Java 技术驿站] [加作者微信交流技术,拉技术群] # JVM内存划分与内存溢出小结 # 1 ...

  3. 深入java虚拟机需要读吗_《深入理解Java虚拟机》读后总结(一)JVM内存模型

    <深入理解Java虚拟机>读后总结 基于Sun HotSpot JVM 直接上图: 从图中看到,JVM内存分为两个主要区域,一个是所有线程共享的数据区,一个是线程隔离数据区(线程私有) 线 ...

  4. java虚拟机手动内存分配_《深入理解java虚拟机》-垃圾收集器与内存分配策略

    如何判断对象已死? 引用计数算法 在对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1:当引用失效时,计数器减1:其中计数器为0的对象是不可能再被使用的已死对象. 引用计数算法的实现很简单 ...

  5. 深入了解java虚拟机编程心得体会_《深入理解Java虚拟机》– 对缓存的理解_零陵上将邢道荣的博客-CSDN博客...

    原文作者:零陵上将邢道荣 原文标题:<深入理解Java虚拟机>-- 对缓存的理解 发布时间:2021-01-26 17:35:15 不才,笔者第一次学习缓存,是在学习redis的时候,是在 ...

  6. java nio有哪些功能_如何真正理解java中的NIO?

    从历史进程来看可能会比较好 早期计算机性能较差的情况下反正你同时也没法同时处理很多io,不如开一个就阻塞在那边,程序员编程也省事,别的花里胡哨的骚操作还未必有这种方式性能高,这个叫做bio 后面cpu ...

  7. java 上下文加载器_【深入理解Java虚拟机 】线程的上下文类加载器

    线程上下文类加载器 线程上下文类加载器( Thread Context ClassLoader) 是从JDK1.2 引入的,类Thread 的getContextClassLoader() 与 set ...

  8. java 接口是抽象类吗_我是如何理解Java抽象类和接口的

    在面试中我们经常被问到:Java中抽象类和接口的区别是什么?然后,我们就大说一通抽象类可以有方法,接口不能有实际的方法啦;一个类只能继承一个抽象类,却可以继承多个接口啦,balabala一大堆,就好像 ...

  9. android中sp的意义_两分钟理解Android中SP与DP的区别

    从一开始写Android程序,就被告知这些常识 长度宽度的数值要使用dp作为单位放入dimens.xml文件中 字体大小的数值要使用sp作为单位,也放入dimens.xml文件中 然后,就没有然后了, ...

  10. python中mainloop什么意思_很难理解python中的Tkinter mainloop()

    好的,我有一个基本的窗口,有一个编辑和查看按钮.按照我的代码,EDIT和VIEW都会返回一条消息"这个按钮没用".我在"主窗口"下创建了这些.我创建了另一个类& ...

最新文章

  1. Linux 性能监控常用命令
  2. 设计模式-建造者模式(05)
  3. ROCK 聚类算法‏
  4. 【Python学习系列十七】基于scikit-learn库逻辑回归训练模型(delta比赛代码2)
  5. 可以输入值的下拉框(select和input的组合使用)
  6. Connection is not open httpClient 的问题解决方案
  7. ASP.NET Core分布式项目实战(oauth2 + oidc 实现 client部分)--学习笔记
  8. SQL Server 索引重建手册
  9. php windows共享内存,给PHP开启shmop扩展实现共享内存
  10. closewin关闭无法返回上一层_紧急关闭iOS13,有史以来跳版本关闭系统
  11. .netframework游戏编程入门——模拟魔兽学院永远的羁绊
  12. php 给富文本里的图片增加ALT、TITLE属性
  13. python如何连续查找字符串_在另一个字符串Python中多次查找字符串
  14. winform:關於画非客户区
  15. 电源线径大小与用电负荷的关系
  16. python爬虫爬取中央气象台每日天气图
  17. python flappy bird游戏
  18. golang的ECB加密代码文件下载
  19. 超详细Netty入门
  20. VBA中的正则表达式(三)

热门文章

  1. 百度网盘html资源,百度网盘目录索引搭建教程:如何把百度网盘文件做成在线html目录...
  2. c语言达内月考试题,达内C培训第一次月考〔附答案〕.doc
  3. Iphone蓝牙通信
  4. R语言使用epiDisplay包的statStack函数基于因子变量通过分层的方式查看连续变量的统计量(均值、中位数等)以及对应的假设检验、通过设置iqr参数强制函数执行参数检验
  5. 四分位距IQR interquartile range
  6. python儿童-少儿Python创意编程课
  7. Python 预测基因变异是否具有相互冲突的临床分类问题
  8. 美利财务平台架构演进
  9. 我国国防是全军的国防_国防部长
  10. STM32学习笔记二、DS18B20单总线上挂载多路采集