Java中Return和Finally运行顺序的实现

简介:

以下这段代码的运行结果是如何的呢?

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. publc int test(){  
  2.     int x;  
  3.     try{  
  4.         x = 1;  
  5.         return x;  
  6.     }catch(Exception e){  
  7.         x = 2;  
  8.         return x;  
  9.     }finally{  
  10.         x = 3;  
  11.     }  
  12. }  

相信对Java比較熟悉的朋友立即会说出正确答案:正常返回1。异常返回2。

我第一次看到这段代码时,对于finally里面的x=3产生了疑惑,不确定最后返回的x是否变成了3。直到从《深入理解Java虚拟机》里面找到了这段代码的字节码,才明确其执行机制。

以下是上面这段Java代码的字节码:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public int test();  
  2.   Code:  
  3.    Stack=1, Locals=5, Args_size=1  
  4.    0:   iconst_1   //将1写入栈顶  
  5.    1:   istore_1   //将栈顶值(1)写入第2个int型本地变量  
  6.    2:   iload_1    //将第2<span style="font-family: Arial, Helvetica, sans-serif;">个int型本地变量load到栈顶(Return语句的開始)</span>  
  7.    3:   istore  4  //保存栈顶值到<span style="font-family: Arial, Helvetica, sans-serif;">第4个int型本地变量</span>,此时x=1  
  8.    5:   iconst_3   //将3写入栈顶(Finally開始)  
  9.    6:   istore_1   //将3写入<span style="font-family: Arial, Helvetica, sans-serif;">第2个int型本地变量</span>  
  10.    7:   iload   4  //将<span style="font-family: Arial, Helvetica, sans-serif;">第4个int型本地变量的值laod到栈顶</span>  
  11.    9:   ireturn    //返回栈顶的值  
  12.    10:  astore_2  
  13.    11:  iconst_2  
  14.    12:  istore_1  
  15.    13:  iload_1  
  16.    14:  istore  4  
  17.    16:  iconst_3  
  18.    17:  istore_1  
  19.    18:  iload   4  
  20.    20:  ireturn  
  21.    21:  astore_3  
  22.    22:  iconst_3  
  23.    23:  istore_1  
  24.    24:  aload_3  
  25.    25:  athrow  

从上面的字节码能够看出,Return语句被分为两部分:iload 4和ireturn,在store和load之间插入的是finally代码。x的值首先被存放到一个指定的位置,再运行finally语句。这时finally中的代码已无法影响返回值了。







本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5219544.html,如需转载请自行联系原作者

相关文章
|
3月前
|
Java
使用IDEA创建项目运行我的第一个JAVA文件输出Helloword
本文介绍了如何使用IDEA(IntelliJ IDEA)创建一个新的Java项目,并运行一个简单的Java程序输出"Hello Word"。文章详细展示了创建项目的步骤,包括选择JDK版本、设置项目名称和路径、创建包和类,以及编写和运行代码。最后,还展示了如何通过IDEA的运行功能来执行程序并查看输出结果。
203 4
使用IDEA创建项目运行我的第一个JAVA文件输出Helloword
|
2月前
|
Java
Java关键字 —— super 详细解释!一看就懂 有代码实例运行!
文章详细解释了Java关键字`super`的用途,包括访问父类的成员变量、调用父类的构造方法和方法,并提供了相应的代码实例。
188 5
Java关键字 —— super 详细解释!一看就懂 有代码实例运行!
|
2月前
|
Java Apache Maven
Java百项管理之新闻管理系统 熟悉java语法——大学生作业 有源码!!!可运行!!!
文章提供了使用Apache POI库在Java中创建和读取Excel文件的详细代码示例,包括写入数据到Excel和从Excel读取数据的方法。
65 6
Java百项管理之新闻管理系统 熟悉java语法——大学生作业 有源码!!!可运行!!!
|
3月前
|
Java Linux
java基础(3)安装好JDK后使用javac.exe编译java文件、java.exe运行编译好的类
本文介绍了如何在安装JDK后使用`javac.exe`编译Java文件,以及使用`java.exe`运行编译好的类文件。涵盖了JDK的安装、环境变量配置、编写Java程序、使用命令行编译和运行程序的步骤,并提供了解决中文乱码的方法。
88 2
|
1月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
80 2
|
2月前
|
分布式计算 大数据 Java
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
44 1
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
|
2月前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
25 1
|
2月前
|
IDE Java 编译器
Java:如何确定编译和运行时类路径是否一致
类路径(Classpath)是JVM用于查找类文件的路径列表,对编译和运行Java程序至关重要。编译时通过`javac -classpath`指定,运行时通过`java -classpath`指定。IDE如Eclipse和IntelliJ IDEA也提供界面管理类路径。确保编译和运行时类路径一致,特别是外部库和项目内部类的路径设置。
202 5
|
2月前
|
Java
java中父类方法return this.对象还是变量,子类去调用this.这个方法的问题
本文探讨了在Java中,当父类的方法返回`this`对象或变量时,子类调用该方法的行为,以及`this`关键字在不同类中调用方法时的指向问题。
20 0
java中父类方法return this.对象还是变量,子类去调用this.这个方法的问题
|
2月前
|
缓存 安全 Java
Java中 final、finally、finalize 有什么区别?
本文详细阐述了Java中`final`、`finally`和`finalize`的区别:`final`用于修饰类、方法和变量以表示不可变性;`finally`是用于确保在`try-catch`结构中无论是否发生异常都能执行的代码块;而`finalize`是`Object`类的方法,用于在对象被垃圾回收前执行清理工作,但在JDK 9中已被标记为弃用。
57 0
Java中 final、finally、finalize 有什么区别?