查了很多资料,都说之前,但是public class test{ 
int i=0; 
public int f(){ 
try{ 
return i; 
}finally{ 
i++; 


public static void main(String args[]){ 
test t = new test(); 
System.out.println(t.i+","+t.f()+","+t.i); 


======================================== 
C:\java>java test 
0,0,1 
======================================= 
C:\java>javap -c test 
Compiled from "test.java" 
public class test extends java.lang.Object{ 
int i; public test(); 
 Code: 
 0: aload_0 
 1: invokespecial #1; //Method java/lang/Object."<init>":()V 
 4: aload_0 
 5: iconst_0 
 6: putfield #2; //Field i:I 
 9: return public int f(); 
 Code: 
 0: aload_0 
 1: getfield #2; //Field i:I 
 4: istore_1 
 5: aload_0 
 6: dup 
 7: getfield #2; //Field i:I 
 10: iconst_1 
 11: iadd 
 12: putfield #2; //Field i:I 
 15: iload_1 
 16: ireturn 
 17: astore_2 
 18: aload_0 
 19: dup 
 20: getfield #2; //Field i:I 
 23: iconst_1 
 24: iadd 
 25: putfield #2; //Field i:I 
 28: aload_2 
 29: athrow 
 Exception table: 
 from to target type 
 0 5 17 any 
 17 18 17 any public static void main(java.lang.String[]); 
 Code: 
 0: new #3; //class test 
 3: dup 
 4: invokespecial #4; //Method "<init>":()V 
 7: astore_1 
 8: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream; 
 11: new #6; //class java/lang/StringBuilder 
 14: dup 
 15: invokespecial #7; //Method java/lang/StringBuilder."<init>":()V 
 18: aload_1 
 19: getfield #2; //Field i:I 
 22: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan 
g/StringBuilder; 
 25: ldc #9; //String , 
 27: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang 
/String;)Ljava/lang/StringBuilder; 
 30: aload_1 
 31: invokevirtual #11; //Method f:()I 
 34: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan 
g/StringBuilder; 
 37: ldc #9; //String , 
 39: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang 
/String;)Ljava/lang/StringBuilder; 
 42: aload_1 
 43: getfield #2; //Field i:I 
 46: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan 
g/StringBuilder; 
 49: invokevirtual #12; //Method java/lang/StringBuilder.toString:()Ljava/l 
ang/String; 
 52: invokevirtual #13; //Method java/io/PrintStream.println:(Ljava/lang/St 
ring;)V 
 55: return }
... 
public int f(){ 
try{ 
return 1; 
}finally{ 
return 2; 


... 
会return 2,原因是return之前执行finally 
但是 
... 
public int f(); 
 Code: 
 0: iconst_1 
 1: istore_1 
 2: iconst_2 
 3: ireturn 
 4: astore_2 
 5: iconst_2 
 6: ireturn 
 Exception table: 
 from to target type 
 0 2 4 any 
 4 5 4 any 
... 
我怎么看也觉得,是return之后,执行finally时再度return,覆盖了原先的返回值 麻烦哪位高手解释一下,谢谢

解决方案 »

  1.   


    test.javapublic class test {
    int i = 0; public int f() {
    try {
    return 1;
    } finally {
    return 2;
    }
    } public static void main(String args[]) {
    testt = new test();
    System.out.println(t.f());
    }
    }
    反编译test.classimport java.io.PrintStream;public class test
    {    int i;    public as()
        {
            i = 0;
        }    public int f()
        {
            return 2;
        }    public static void main(String args[])
        {
            test t = new test();
            System.out.println(t.f());
        }
    }
      

  2.   

    public as()
    as 应该是 test
      

  3.   

    在try-finally语句中 finally块总是会被执行 当控制离开try块时
    无论try块是正常结束还是强行(abruptly) 
    如果两块都是abruptly 那么try块中的理由就会被丢弃 
      

  4.   

    一个方法只可能返回一个值.
    java中不允许确定一定不可执行的代码的出现 如 return 后的语句
    既然 finally块可以通过编译说明 finally块一定是可以执行的.当return 1 这个时候方法还没有执行完
    最终执行return 2 这时第一个返回的哪个值就
    会失效.
      

  5.   

    finally 不管在什么情况下都是会执行的,和 c#的析构函数一样的,都是由虚拟机来执行的,不受人操作,我们能操作的就是在finally 里做相应的关闭操作,如输入流的关闭,数据库的连接关闭等等
      

  6.   

    在try{}中,用return,break退出,程序还是要跳到finally{}块下执行。
    但try{}中用exit()退出时,就不会这样,finally{}不会执行。
      

  7.   

    return 了就不会在执行了。
      

  8.   

    finally,,,在异常中,,都会执行...除非强行退出..如用EXIT()
      

  9.   

    finally()是在所有CATCH()都处理完后才执行....
      

  10.   

    某位伟人说过:“回帖不看贴的,比看贴不回贴更可怕”主要是“return之前还是之后”这一句,请给出证据,谢谢
      

  11.   

    会执行finnally,只有一种情况不会执行那就是System.exit(0);
      

  12.   

    无论如何都会执行finally,哪怕又return,只有在try中exit了就不执行后面的了。
      

  13.   


    package temporary;public class FinallyTest { /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub for(int i=1;i<5;i++){
    f(i);
    }
    } public static void f(int i){
    System.out.println("初始化的值需要清理");
    try{
    System.out.println("point 1");
    if(i == 1)
    return;
    System.out.println("point 2");
    if(i == 2)
    return;
    System.out.println("point 3");
    if(i == 3)
    return;
    System.out.println("End");
    return;
    }finally{
    System.out.println("执行清理工作");
    }
    }
    }
    在一个方法中,程序可以从多个点返回,并同时可以保证重要的清理工作仍然被执行
      

  14.   

    运行结果如下:
    初始化的值需要清理
    point 1
    执行清理工作
    初始化的值需要清理
    point 1
    point 2
    执行清理工作
    初始化的值需要清理
    point 1
    point 2
    point 3
    执行清理工作
    初始化的值需要清理
    point 1
    point 2
    point 3
    End
    执行清理工作
      

  15.   

    如果try-catch-finally语句中
    try块里有return语句,那么finally语句的执行优先于return
      

  16.   

    public class test{ 
    int i=0; 
    public int f(){ 
    try{ 
    return i; 
    }finally{ 
    i++; 


    public static void main(String args[]){ 
    test t = new test(); 
    System.out.println(t.i+","+t.f()+","+t.i); 


    代码就编译过不了呀.
    f()方法必须保证返回一个int值呀 
      

  17.   

    为何大家回帖都不看贴?注意,我问的是“finally是在return之前还是之后执行”
    我认为是return之后执行,原因:
    将下列代码反编译...
    public int f(){ 
    try{ 
    return i; 
    }finally{ 
    i++; 


    ...得到...
    public int f(); 
     Code: 
     0: aload_0 
     1: getfield #2; //Field i:I 
     4: istore_1 
     5: aload_0 
     6: dup 
     7: getfield #2; //Field i:I 
     10: iconst_1 
     11: iadd 
     12: putfield #2; //Field i:I 
     15: iload_1 
     16: ireturn      <<注意这里已经return了
     17: astore_2 
     18: aload_0 
     19: dup 
     20: getfield #2; //Field i:I 
     23: iconst_1 
     24: iadd         <<这里才++
     25: putfield #2; //Field i:I 
     28: aload_2 
     29: athrow 
     Exception table: 
     from to target type 
     0 5 17 any 
     17 18 17 any 
    ...但是很多人却说finally在return之前执行,为什么?
    哪位高手可以解释一下?谢谢
    回帖不看贴的,就免了
      

  18.   

    我单步跟踪了一下:
    public static void f(int i){
            System.out.println("初始化的值需要清理");   //1,6,14,24
            try{
                System.out.println("point 1");        //2,7,15,25
                if(i == 1)                            //3,8,16,26
                    return;                           //5,13,23,34
                System.out.println("point 2");        //9,17,27
                if(i == 2)                            //10,18,28
                    return;                           //11
                System.out.println("point 3");        //19,29
                if(i == 3)                            //20,30
                    return;                           //21
                System.out.println("End");            //31
                return;                               //32
            }finally{
                System.out.println("执行清理工作");   //4,12,22,33
            }
        }
      

  19.   

    第一次,确实是finally先执行再return,但是随后的就先是return再finally,再i==1处的return,
      

  20.   

    没看你的代码 也看不懂那些代码
    问return后finally里面的句子还会不会执行,什么时候执行
    finally里的句子肯定会被执行 return语句之后 方法结束之前return只是给了方法一个结果 没finally那方法就结束 有finally 那就继续执行finally 方法的结果暂时放在那 finally里没再return 那方法的结果就是原来那个 再return 就覆盖掉原来那个 我想应该有个临时变量存放方法的返回结果的 return只是相当于给那个临时变量赋值以上纯个人推测 没理论依据
      

  21.   

    书上说的那个return之前 可能指的是方法返回前 而不是return语句之前 如果是return语句之前 那就搞笑了 我try块里没异常代码也没结束 你凭什么去执行finally块
      

  22.   


    public class Test {
        int i = 0;    public int f() {
            try {
                return (i = returnCall());
            } finally {
                System.out.println("finally 里来了!");
                i++;
            }
        }
        
        private int returnCall(){
            System.out.println("return 里来了!");
            return 1001;
        }    public static void main(String args[]) {
            Test t = new Test();
            System.out.println(t.f());
        }
    }跟踪了一下,和楼主达成共识,是先执行return statement,后finally里的statement!
    method的return和 statement的return好像是不同吧,产生歧义了,偶认为有些书写的。
      

  23.   

    同学,严重握手ing!!! hoho~
      

  24.   

    asdfasfasdf
      
    *****************************************************************************
    欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码) http://www.cnblogs.com/feiyun0112/archive/2006/09/20/509783.html
      

  25.   

    其实只要不是答非所问,那看不看没什么所谓的另外,那个说之前的,并不是书上看的
    而是网上流传的所谓JAVA面试题之类的,所有人都信誓旦旦地说是之前,弄到我也很怀疑是不是自己搞错了再等一下,睡觉前结贴多谢各位解答
      

  26.   

    顺便贴一些给大家看某面试题:
    43、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
    会执行,在return前执行。
    这里,是.NET版上的一个
    http://topic.csdn.net/u/20070405/15/229f5b9a-75a0-479e-aeb3-63906c9a2dfc.html
    里面4、5颗星星的人都说之前,但是都没有给出令人信服的证据
    难道C#又有不同?
      

  27.   

    学习!呵呵,楼主想问题真是细啊!一直认为是在return之前先执行finally
    不过这下感觉是先执行return,执行了以后,方法并没有马上退出,而是再到finally里面去执行!public class xx { public static void main(String[] args) {
    System.out.println(get());
    }

    public static String get() {
    try {
    return tt();
    } catch (Exception e) {
    return "";
    } finally{
    System.out.println("finally...");
    }
    }

    public static String tt() {
    System.out.println("ttt........");
    return "ss";
    }
    }
      

  28.   

    答:楼主的认真精神令人敬佩!而且问题问得好!可惜楼主查了很多资源,恰恰漏了JAVA祖师爷James Gosling的书。他的书上早已讨论过你的这种情况,凭楼主这样很聪明的人,提醒一下就知道了。
    以下就是根据:
    见:section 12.4节。或者我在此摘录一下:A finally clause is always entered with a reason. That reason may be that the try code finished normally, that it executed a control flow statement such as return, or that an exception was thrown in code executed in the TRy block. The reason is remembered when the finally clause exits by falling out the bottom. However, if the finally block creates its own reason to leave by executing a control flow statement (such as break or return) or by throwing an exception, that reason supersedes the original one, and the original reason is forgotten. For example, consider the following code:try {
        // ... do something ...
        return 1;
    } finally {
        return 2;
    }When the TRy block executes its return, the finally block is entered with the "reason" of returning the value 1. However, inside the finally block the value 2 is returned, so the initial intention is forgotten. In fact, if any of the other code in the try block had thrown an exception, the result would still be to return 2. If the finally block did not return a value but simply fell out the bottom, the "return the value 1" reason would be remembered and carried out.
    主要含义是说(若不对请看原文吧):从try{}块进入到finally{},一是:try代码正常执行完或由如return语句所执行的控制流 二是:抛出异常。另外例子说明的是:当try块执行它的return 1 语句后,带着“返回值是1的'原因'”进入finally。然而,在finally内部,执行return 2,要将值2返回,因而"initial intention is forgotten"(即:原来的值被'遗忘'了),即使try块中抛出异常,返回值仍然是2.若finally中没有return语句,则"return the value 1这个'原因'"会被记住并返回值1.
      

  29.   

    答:现在大家应该很清楚吧,James Gosling书中讲得很清楚了:执行return 语句之后再进入finally。
      

  30.   

    我在22楼的,第一次先是finally再return,大家怎么解释