黑马程序员技术交流社区

标题: 回答一个朋友的问题,顺便科普try{}finally{}的关系 [打印本页]

作者: 呢喃的喃呢    时间: 2014-1-12 18:47
标题: 回答一个朋友的问题,顺便科普try{}finally{}的关系
本帖最后由 呢喃的喃呢 于 2014-1-12 18:55 编辑

提问帖:http://bbs.itheima.com/thread-105030-1-1.html
提问内容:

  1. try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code什么时候被执行?
  2. 网上搜索的答案,有回答是之前的,可是我自己写了代码理解为是之后,因为我理解的return语句执行完后,不是马上返回到其他程序执行,而是跳出try{},然后把finally{}执行完了再跳转;不知道我的理解对不对?还请高手指点,以下是我的实验代码:
复制代码



以下是我的回复
如果是返回值的原因使得你有这样的疑问
其实很简单的道理。表示局部变量的道理是没有完全明白,我就说下,返回值为什么没有你想象中改变的原因。
在JAVA机制里面 jvm管理内存很复杂,我就不扯JVM的机制了。
既然你把x定义在了try 之外。哪就是说 try catch finall都可以拿到这个变量的引用,这个没有争议吧。(如果你在try中定义,它就是属于一个局部变量,你finally使用根本就会编译出错的)。哪么根据自动包装原则,这个数字会变成Integer对象。
JVM管理内存的方法就是对象引用。扯了很多回到正题

你的try中有return 会返回结果。返回的还是x.至于你为什么返回的x还是原数,而不是++x的结果,是因为你可以理解成为,finally是在return 之后执行的。finally里面执行的++x是影响不到你try或者catch时候return 返回的结果的,除非你在finally里面使用return.


上面说了很多废话 简明说就是 finally是在try return 之后执行的,你在finally这里进行的任何操作无法改变try 或 catch return哪一瞬间的引用对象值。除非你在finally里面再次return



如果不是返回值的困扰,知识单纯的不知道他们的顺序

不管是try 还是catch里面是否使用了return都无法取之后finally的执行,除非你用了System.exit(0),finally才会不执行
作者: mrwise1991    时间: 2014-1-12 19:36
我们知道一般的方法中,如果程序执行过程中遇到了return就会跳出该函数体,该函数就执行完毕了,所以这里应该也是一样的
作者: 大大老伴要跪IT    时间: 2014-1-12 22:15
准确的说是在return之间执行的。但是有一个特殊情况:在代码执行到finally之前,jvm就退出了(System.exit(0))。给你一段代码理解下。
  1. public class FinallyTest {
  2.         public static void main(String[] args) {
  3.                 int result = method3();
  4.                 System.out.println(result);
  5.         }
  6.         private static int method3() {
  7.                 int a = 10;
  8.                 try {
  9.                         System.out.println(a / 0);
  10.                         System.out.println("a1:" + a);
  11.                 } catch (ArithmeticException ae) {
  12.                         System.out.println("a2:" + a); // a2:10
  13.                         a = 20;
  14.                         return a; //这个时候,在内存中就会有一个路径产生,该路径返回值是20.
  15.                                           //但是,它看到了finally代码块,所以,继续执行finally里面的内容               
  16.                                           //当finally里面结束后,会回到以前的执行路径。
  17.                 } finally {
  18.                         a = 30;
  19.                 }
  20.         return a;
  21.         }
复制代码

作者: 呢喃的喃呢    时间: 2014-1-13 21:36
其实我没想把话题聊的很深,如果再把下探讨的话就要到JVM的内存管理机制了。会给目前学习阶段的朋友造成很多困扰,因为目前了解这些完全没有意义,反而会浪费他们有限的脑力去思考这些更深入的问题。
确切并且恰当的说,finally会在return之前被执行,正如上面朋友说的。执行完finally后会回到return再进行返回,如果finally有return则不会回到try或catch的return,但是说道这里可能有的朋友就会有疑问,为什么在finally里面改变了相同引用对象的内容 却无法返回(不完全是无法改变)。所以怕牵扯出这些话题,对初学者造成困扰。不过还是感谢上面这位朋友的补充。
作者: 呢喃的喃呢    时间: 2014-1-13 21:37
java的亮点在于让很多程序员(不做底层部分),不用去关心他是怎么内存管理,怎么垃圾回收的,所以在不准备向底层发展 深入JVM的话,还是点到为止,可在将来的某天 有精力来再研究这些东西。因为他毕竟对你的J2EE或J2ME开发没有任何帮助。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2