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

    xiaoxiao2021-03-25  77

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

    题目大意 : 当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 */ }
    转载请注明原文地址: https://ju.6miu.com/read-17419.html

    最新回复(0)