在try中存在return情况下,finally的执行情况

之前面试时被问个问题,确实没有考虑过.

题目大意 : 当try、catch、finally中都存在return时,最后返回的为哪个的return值.

结论 :就上面的问题答案应该是finally中的return会覆盖掉try或catch中的return语句.


两篇很清楚的参照 :

原文 : Java finally语句到底是在return之前还是之后执行?

结论 :
finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中 return已经确定的返回值,若finally里也有return语句则覆盖try或catch中的return语句直接返回。


原文 : finally块的问题(finally block does not complete normally)

结论 :

当finall块中包含return语句时,Eclipse会给出警告“finally block does not complete normally”,原因分析如下:

1、不管try块、catch块中是否有return语句,finally块都会执行。
2、finally块中的return语句会覆盖前面的return语句(try块、catch块中的return语句),所以如果finally块中有return语句,Eclipse编译器会报警告“finally block does not complete normally”。

3、如果finally块中包含了return语句,即使前面的catch块重新抛出了异常,则调用该方法的语句也不会获得catch块重新抛出的异常,而是会得到finally块的返回值,并且不会捕获异常。

结论,应避免在finally块中包含return语句。如果你在前面的语句中包含了return语句或重新抛出了异常,又在finally块中包含了return语句,说明你概念混淆,没有理解finally块的意义。


由两篇很清楚的参照,进行的测试,还涉及的由java只有值传递.

可以通过debug,更清楚的了解到具体的执行步骤,finally执行的时间.
public class FinallyReturn2 {
    public static void main(String[] args) {
        System.out.println("result b : " + findReturn2());
    }

    /**
     * 测试在try中return执行之后,finally中内容是否执行
     * 以及最终返回值为try中结果,或者为finally结果
     * 
     * 根据debug的情况,说明try中的return是执行的,但同时执行之后仍然等待finally中代码的执行结果
     */
    public static int findReturn2() {
        int b = 0;
        try {
            System.out.println("try block.");
            b++;
            return b;
        } catch (Exception e) {
            System.out.println("catch block.");
        } finally {
            System.out.println("finally block.");
            b++;
            return b;
        }
    }
    /*
     * result :
     * try block.
     * finally block.
     * result b : 2
     * 结果 : 最终返回的结果为finally的结果. 
     * 结论 : 在try中存在return情况,finally仍会执行. 且执行时间是在try中return执行之后,返回之前.
     *       且在finally中存在return的情况下,会直接覆盖try中返回.
     */
}
public class FinallyReturn3 {

    public static void main(String[] args) {
        System.out.println("result b : " + findReturn3());
    }

    /**
     * 比较findReturn2,去掉了finally中的return
     * 查看最后的返回结果是否为finally执行后的结果
     * @return
     */
    public static int findReturn3() {
        int b = 0;
        try {
            System.out.println("try block.");
            b++;
            return b;
        } catch (Exception e) {
            System.out.println("catch block.");
        } finally {
            System.out.println("finally block.");
            b++;
            System.out.println("finally block b : " + b);   // 执行finally后b的值
        }
        return b;
    }
    /*
     * try block.
     * finally block.
     * finally block b : 2
     * result b : 1
     * 结果 : 最终返回的为try中return.
     * 结论 : finally成功执行并更改了b的值,但此处并没有对try中的return值产生影响.
     */
}
import java.util.HashMap;
import java.util.Map;

public class FinallyReturn4 {

    public static void main(String[] args) {
        System.out.println("result map : " + findReturn4().get("key"));
    }

    /**
     * 比较findReturn3,将2中的基础类型改为引用类型
     * 查看最后返回结果是否为finally执行之后的结果 - (表明了java中是进行值传递).
     */
    public static Map<String, String> findReturn4() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "init");
        try {
            System.out.println("try block.");
            map.put("key", "try");
            return map;
        } catch (Exception e) {
            System.out.println("catch block.");
        } finally {
            System.out.println("finally block.");
            map.put("key", "finally");
            System.out.println("finally block map : " + map.get("key")); 
        }
        return map;
    }
    /*
     * result : 
     * try block.
     * finally block.
     * finally block map : finally
     * result map : finally
     * 
     * 结果 : 最终仍返回try中return值 - debug单步执行表明
     * 结论 : finally成功执行并更改了b的值,同时对try中的return值产生影响.
     * 原因 : java中只有值传递,对于引用类型,try中return返回的为map的地址拷贝.
     */

}
import java.util.HashMap;
import java.util.Map;

public class FinallyReturn5 {

    public static void main(String[] args) {
        System.out.println("result map : " + findReturn5().get("key"));
    }

    public static Map<String, String> findReturn5() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "init");
        try {
            System.out.println("try block.");
            map.put("key", "try");
            return map;
        } catch (Exception e) {
            System.out.println("catch block.");
        } finally {
            System.out.println("finally block.");
            map.put("key", "finally");
            map = null;     // 比较4中添加的语句,代码作用只是将map指向的引用变更为null
            map.clear();    // 而非clear
        }
        return map;
    }
    /*
     * result : 
     * try block.
     * finally block.
     * result map : finally
     */
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值