A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 宗士为 中级黑马   /  2012-5-21 16:09  /  2468 人查看  /  16 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

这段代码的结果是1,但是很弄不明白为什么是1不是2  
求明白人解释   最好说明白点哈    最怕的就是原理流程问题

public  class Test {

   public static void main(String[] args) {

          System.out.println(new Test().test());;

     }

     static int test()

     {

          int x = 1;

          try

          {

              return x;

          }

          finally

          {

              ++x;

          }

     }

}

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

16 个回复

倒序浏览
本帖最后由 杨梦宇 于 2012-5-21 16:32 编辑

执行的次序应该是,先执行try里面的语句 此时x的值会被记录,但是不会马上返回,接着执行finnally里面的语句 再返回 如果不好理解 请看下面的代码
  1. public class testReturn {

  2.     public static int test() {
  3.         try {
  4.             return fun1();
  5.         } catch (Exception e) {
  6.         } finally {
  7.             return fun2();
  8.         }
  9.     }

  10.     public static int fun1() {
  11.         System.out.println("fun1被执行了");
  12.         System.out.println("fun1的确被执行了,返回么?");
  13.         return 1;
  14.     }

  15.     public static int fun2() {
  16.         System.out.println("fun2被执行了");
  17.         System.out.println("fun2的确被执行了,返回么?");
  18.         return 2;
  19.     }

  20.     public static void main(String[] args) {
  21.         System.out.println(testReturn.test());
  22.     }
  23. }
复制代码
结果:fun1被执行了
      fun1的确被执行了,返回么?
      fun2被执行了
      fun2的确被执行了,返回么?
      2

//注意,结果中第二句之后并没有返回值(但此时x的值会被记 录)!程序之后暂时给finally操纵了,如果finally“把握住了机会” 用return返回了,那返回的是现在x的值,如果没把握住,不管它执行了什么代码,返回的x值还是执行try那个时期记录的。

点评

如果finally“把握住了机会” 用return返回了,那返回的是现在x的值...........................这个机会是指????  发表于 2012-5-21 16:43

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 你说的机会是指神马?

查看全部评分

回复 使用道具 举报
本帖最后由 罗文杰 于 2012-5-21 16:59 编辑

  static int test()

     {

          int x = 1;

          try

          {

              return x;   //这句已经把x的值的返回了,就是说这个test()函数的返回值为x,而你的x这时还没有自增,所以值为1

          }

          finally

          {

              ++x;  //虽然这句一定会执行,但不是你的函数返回值。

          }

     }
如果你想要2这个结果的话,可以吧++x 写在try模块里,把return语句写在finally模块里。

           try

          {

              ++x;

          }

          finally

          {

              return x;

          }

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
楼上没有切中要害,实际上楼主可能知道一个关于这个问题的一个理论,该理论说finally语句块会执行,并在try之前执行。这是个很流行的错误观念
回复 使用道具 举报
  1. package it.itcast.demo;

  2. public class Test {
  3.         public static void main(String[] args) {
  4.                 //这句话直接写成Test.test(),效果是一样的
  5.                 System.out.println(new Test().test());

  6.         }

  7.         static int test()

  8.         {

  9.                 int x = 1;
  10.                

  11.                 try

  12.                 {
  13.                         System.out.println("try...return执行前");

  14.                         return  x;        //return--->返回一个值,表示此语句结束
  15.                        

  16.                 }

  17.                 finally

  18.                 {
  19.                         System.out.println("finlly在return前执行,而且不影响返回结果");
  20.                         ++x; //这个地方不影响结果;

  21.                 }

  22.         }
  23. }
复制代码
看一下运行结果;
try...return执行前
finlly在return前执行,而且不影响返回结果
1
像这种可以自己写几个输出语句就知道顺序了的

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 赞一个!

查看全部评分

回复 使用道具 举报
异常处理有多种处理语句:1、try{被检测的代码} catch{处理异常的代码};2、try{被检测的代码} catch{处理异常的代码};finally{一定会执行的代码};3、try{被检测的代码} finally{一定会执行的代码};
finally{}中一定会执行的代码一般是用于关闭资源的代码,例如关闭流资源。
但是finally{一定会执行的代码}只有一种情况不会执行:当执行到System.exit(0),finally不执行了。
回复 使用道具 举报
Fc10232 发表于 2012-5-21 16:41
看一下运行结果;
try...return执行前
finlly在return前执行,而且不影响返回结果

请问你最后的结论是什么呢?
回复 使用道具 举报
Fc10232 发表于 2012-5-21 16:41
看一下运行结果;
try...return执行前
finlly在return前执行,而且不影响返回结果

把握住了机会就是,在finally里面有return语句 将程序结束了
回复 使用道具 举报
进一步的佐证:看下面代码(这里finally“把握住了机会” 返回的是经过finally处理过的x :2)
  1. public  class Test {

  2.    public static void main(String[] args) {

  3.           System.out.println(new Test().test());;

  4.      }

  5.      static int test()

  6.      {

  7.           int x = 1;

  8.           try

  9.           {

  10.               return x;

  11.           }

  12.           finally

  13.           {

  14.               return ++x;

  15.           }

  16.      }

  17. }
复制代码
结果2


评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 再给你一分 - -!

查看全部评分

回复 使用道具 举报
杨梦宇 发表于 2012-5-21 16:50
把握住了机会就是,在finally里面有return语句 将程序结束了

最后的结果就是x没有发生变化,
顺便跟他说了一下程序的运行顺序
回复 使用道具 举报
徐然 黑马帝 2012-5-21 17:17:49
11#
本帖最后由 徐然 于 2012-5-21 17:33 编辑

首先,在异常中的执行顺序是1,try{};代码块中的代码
                          2.catch(){}中的处理代码(除return外)
                                       3.finally
                                       4.return
这样一列就看出来了,你把return放到try里面,自然是return先执行,finally后执行
那么return返回的结果已经确定了,它只是等finally执行完,就执行返回,至于finally运行的是什么,它并不理会
除非finally里也有一个return,那么,这个return的值就会覆盖try中的return
回复 使用道具 举报
徐然 发表于 2012-5-21 17:17
首先,在异常中的执行顺序是1,try{};代码块中的代码
                          2.catch(){}中的处理代码 ...

在try时期,最终返回结果并没有确定,如果finally里面有return返回的话 得按finally的执行结果来返回 没有的话才不用理会finally的操作
回复 使用道具 举报
我觉得:try{}catch(){}finally{}的运行原理是这样的..首先在try块里面捕捉异常 要是没有异常接下来执行finally{}块,有异常直接从有异常的地方跳转到catch块中! 然后执行finally ,要是在try中遇到return 或者其他的跳转则先跳到finally中然后在跳转.但是在跳转的过程中出现问题 则进入catch中 然后直接跳出.....
回复 使用道具 举报
徐然 黑马帝 2012-5-21 17:35:00
14#
杨梦宇 发表于 2012-5-21 17:32
在try时期,最终返回结果并没有确定,如果finally里面有return返回的话 得按finally的执行结果来返回 没 ...

是的,谢谢,那会忽略了,发出来才看见,已经修改了
回复 使用道具 举报
关键问题还是在try{}finally{}
你的代码之行这这样,先之行try{}里面的return x;不管return x;是否执行成功,finally{}里面的++x;最后都是要被执行的。
当你在main函数里面输出的时候,这个方法先就已经返回x了,而这个x依旧是1;
如果你          try

          {
                          ++x;
              

          }

          finally

          {
           return x;
             }
          这样就结果就是2了~
回复 使用道具 举报
public class Test {
        public static void main(String[] args) {
                 System.out.println(new Test().test());
        }
        /*函数调用子函数并得到结果的过程,好比主函数准备一个罐子,当子函数要返回结果时,
        先把结果放在罐子里,然后再将程序逻辑返回到主函数。
        程序中返回值是在finally执行过程中就返回给了主函数
        */
        static int test(){
         int x = 1;
         try{
             return x;
                // ++x;
         }
         finally{
        //         return ++x;
                ++x;
         }
    }
}
回复 使用道具 举报
这个问题是关于finally在什么时候执行的问题,此程序finally会在return语句之前先执行,
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马