首先得了解

try{
    //…………other code
    return ……;
}finally{
    //code
}

finally中的code会被执行,现在要考虑是code在return之前执行呢还是在return之后执行呢?


接下来写代码测试一下

public class Test{
    static int x = 1;
    public static void main(String[] args){
        System.out.println("return:"+new Test().test());
        System.out.println("main:"+x);
    }
                                                                                                                                                                                                                                                                                           
    public int test(){
        try{
            return x;
        }finally{
            x += 1;
            System.out.println("finally:"+x);
        }
    }
}

执行结果:

spacer.gif143730836.jpg

分析结果:

先输出finally:2,即表明先finally中的code在return之前执行

接下来输出return:1,注意,此时x的值是1,即表明return是在finally中的x+=1;前执行的


矛盾出来了,到底是执行finally中的code还是先return?


张孝祥老师说是finally中的code是在return中间执行的,观点如下:

主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。”


个人理解:

1、子函数test()先把x的值return到主函数

2、然后执行完finally中的code输出 finally:2

3、主函数输出从test()得到的结果 return:1

4、主函数继续执行输出 main:2


再次确定一下:

public class Test{
    static int x = 1;
    public static void main(String[] args){
        System.out.println("return:"+new Test().test());
        System.out.println("main:"+x);
    }
                                                                                 
    public int test(){
        try{
            return x;
        }finally{
            x += 1;
            System.out.println("finally:"+x);
            return 3;//新加代码
        }
    }
}

在上面的程序中加一行代码,即在finally中也增加return

执行结果:

150144876.jpg

可以看到test()返回值为3,即为finally中的return值


主函数得到返回值并不会马上输出,而是要等finally执行完,然而finally中也有return,此时主函数更新得到的返回值3,(LZ测试在finally的return语句后添加代码会出现编译错误),finally执行return后才真正让主函数继续执行。


经验证,在try{}finally{}模块中,break与return是同样的。finally不被执行的唯一情况就是在之前的代码中包含

System.exit(0);