写了一个简单的程序如下:public class Test {
public static void main(String[] args) {
int b = test();
System.out.println(b);
} public static int test() {
                int a = 0;
try {
int a = 1;
return a;
} finally {
a = 2;
System.out.println(a);
}
}
}结果输出是:
2
1把程序改成如下:public class Test {
static int a = 0;
public static void main(String[] args) {
int b = test();
System.out.println(b);
System.out.println(a);
} static int test() {
try {
a = 1;
return a;
} finally {
a = 2;
System.out.println(a);
}
}
}输出为:
2
1
2finally是先于return执行的,疑惑也正由于此,我的猜想是执行到了return语句的时候,会先把a的值压入到堆栈之类的内存区,然后再去执行finally,最后到了return才出栈。不知道这样理解对不对,请高手指教。

解决方案 »

  1.   

    我记得老紫竹前辈有篇blog总结了一下各种情况的结果,找不到鸟。。
      

  2.   

    别把return当作是一个语句,它只是触发一系列操作而已:
    1、设置返回值,以前写过QuickBasic么?函数返回值不能直接return,而是result = 1;
    2、执行finally语句序列,因为finally是可以嵌套的;
    3、清理函数上下文环境;
    4、返回主调函数。如果把return直接理解为语句栈之类的东西,那么你就没法解释下面这个效果了:
    public int test() {
      try {
        return 1;
      } finally {
        return 2;
      }
    }
      

  3.   

    try
    {
    return (expression);
    }
    finally
    {
    {finally code block}
    }
    JVM执行过程的伪代码是:
    variable temp_variable;
    try
    {
      temp_variable = (expression);
    }
    catch(Throwable ex)
    {
    {finally code block}//同下面解释
    throw ex;
    }
    {finally code block}
    //如果finaly code block 抛出异常,或包含return 语句,则跟java语法一样,向外抛出异常,或者return,不会执行后续的语句。
    return temp_variable;public int test() {
       try {
       return 1;
       } finally {
       return 2;
       }
    }
    这段代码中对应的finally code block包含return 2,所以会返回2
    static int test() {
     try {
     a = 1;
     return a;
     } finally {
     a = 2;
     System.out.println(a);
     }
     }
    }
    这段代码对应的return {expression}是a,求值是1并保存在temp_variable里,
    {finally code block}里a=2不会影响返回值,但在返回之前会先在控制台输出2,然会返回temp_variable里的1.(即:先输出2,再返回1)
      

  4.   

    javap -c Test运行下,一目了然,无需各种猜测
      

  5.   

    同3楼啊,可以视为return返回的值存储到一个java自动产生的变量里面,finally里直接将a的值改变了
      

  6.   


    public class Test {
        public static void main(String[] args) {
            int b = test();
            System.out.println(b);
        }    public static int test() {
            int a = 0;
            try {
                a = 1;
                return a;
            } finally {
                a = 2;
                System.out.println(a);
            }
        }
    }public class Test extends java.lang.Object{
    public Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   returnpublic static void main(java.lang.String[]);
      Code:
       0:   invokestatic    #2; //Method test:()I
       3:   istore_1
       4:   getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;
       7:   iload_1
       8:   invokevirtual   #4; //Method java/io/PrintStream.println:(I)V
       11:  returnpublic static int test();
      Code:
       0:   iconst_0
       1:   istore_0
       2:   iconst_1
       3:   istore_0
       4:   iload_0
       5:   istore_1
       6:   iconst_2
       7:   istore_0
       8:   getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;
       11:  iload_0
       12:  invokevirtual   #4; //Method java/io/PrintStream.println:(I)V
       15:  iload_1
       16:  ireturn
       17:  astore_2
       18:  iconst_2
       19:  istore_0
       20:  getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;
       23:  iload_0
       24:  invokevirtual   #4; //Method java/io/PrintStream.println:(I)V
       27:  aload_2
       28:  athrow
      Exception table:
       from   to  target type
         2     6    17   any
        17    18    17   any}
      

  7.   

    不清楚為啥在test方法中有兩次打印
    仿佛有兩句System.out.println(a);一樣
      

  8.   

    我认为啊,就上面的结果来说,并不难解释!不去考虑物理上的东西,只看程序就可以解释!我的解释为:
    int b = test();
    System.out.println(b);
    b的输出肯定是在test()函数执行完之后。
    finally {
     a = 2;
     
     }
    是在函数最后被执行的,即test()执行结束之前要被执行,所以System.out.println(a)先输出。我又跟着程序走了下,结果和上面说的差不多