深入理解finally关键字,Finally到底是在return前面执行还是在return后面执行

一:2种finally不会执行的情况

  a.在try语句之前就return了

  b.try语句中有System.exit();语句

二:finally语句在return执行之后,return返回之前执行

  例1:

public class FinallyTest1 {
    public static void main(String[] args) {
        test1();
    }
    public static int test1(){
        int b=20;
        try {
            System.out.println("try block");
            return b += 80;
        }
        catch (Exception e) {
            System.out.println("catch block");
        }
        finally {
            System.out.println("finally block");
            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }
        }
        return b;
    }
}

console:

try block
finally block
b>25, b = 100
View Code

说明:在return b += 80;后先执行finally语句

再来一个例子加强这个事实

例2

public class FinallyTest1 {
    public static void main(String[] args) {
        System.out.println(test11());
    }
    public static String test11() {
        try {
            System.out.println("try block");
            return test12();
        } finally {
            System.out.println("finally block");
        }
    }
    public static String test12() {
        System.out.println("return statement");
        return "after return";
    }
}

console:

try block
return statement
finally block
after return
View Code

说明:先执行了return 语句中的方法,然后返回值

 

三:如果finally中有return语句呢?

public class FinallyTest1 {
    public static void main(String[] args) {
        System.out.println(test2());
    }
    public static int test2() {
        int b = 20;
        try {
            System.out.println("try block");
            return b += 80;
        } catch (Exception e) {
            System.out.println("catch block");
        } finally {
            System.out.println("finally block");
            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }
            return 200;
        }
        // return b;
    }
}

console:

try block
finally block
b>25, b = 100
200
View Code

说明:finally里的return直接返回了,就不管try中是否还有返回语句,这里还有个小细节需要注意,finally里加上return过后,finally外面的return b就变成不可到达语句了,也就是永远不能被执行到,所以需要注释掉否则编译器报错。

四:如果finally语句中没有return语句覆盖返回值,那么原来的返回值可能因为finally里的修改而改变也可能不变。

 

public class FinallyTest1 {
    public static void main(String[] args) {
        System.out.println(test3());
    }
    public static int test3() {
        int b = 20;
        try {
            System.out.println("try block");
            return b += 80;
        } catch (Exception e) {
            System.out.println("catch block");
        } finally {
            System.out.println("finally block");
            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }
            b = 150;
        }
        return 2000;
    }
}

console:

try block
finally block
b>25, b = 100
100
View Code

对比下面的这个程序

public class FinallyTest1 {
    public static void main(String[] args) {
        System.out.println(getMap().get("KEY").toString());
    }
    public static Map<String, String> getMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("KEY", "INIT");
        try {
            map.put("KEY", "TRY");
            return map;
        }
        catch (Exception e) {
            map.put("KEY", "CATCH");
        }
        finally {
            map.put("KEY", "FINALLY");
            map = null;
        }
        return map;
    }
}

console:

FINALLY
View Code

说明:为什么测试用例1中finally里的b = 150;并没有起到作用而测试用例2中finally的map.put("KEY", "FINALLY");起了作用而map = null;却没起作用呢?这就是Java到底是传值还是传址的问题了

    1.值传递不可以改变原变量的内容和地址;

   2.引用传递不可以改变原变量的地址,但可以改变原变量的内容;

    3.注意String str = new String("good")特殊,因为String是个特殊的final类,所以每次对String的更改都会重新创建内存地址并存储(也可能是在字符串常量池中创建内存地址并存入对应的字符串内容),但是因为这里String是作为参数传递的,在方法体内会产生新的字符串而不会对方法体外的字符串产生影响。相当于值传递

 

五:是不是每次返回的一定是try中的return语句呢?那么finally外的return b不是一点作用没吗?

public class FinallyTest1 {
    public static void main(String[] args) {
        System.out.println(test4());
    }
    public static int test4() {
        int b = 20;
        try {
            System.out.println("try block");
            b = b / 0;
            return b += 80;
        } catch (Exception e) {
            b += 15;
            System.out.println("catch block");
        } finally {
            System.out.println("finally block");
            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }
            b += 50;
        }
        return b;
    }
}

console:

try block
catch block
finally block
b>25, b = 35
85
View Code

 

六:若发生异常,catch语句中的return语句和try中的return语句的情况一模一样

public class FinallyTest1 {
    public static void main(String[] args) {
        System.out.println(test5());
    }
    public static int test5() {
        int b = 20;
        try {
            System.out.println("try block");
            b = b /0;
            return b += 80;
        } catch (Exception e) {
            System.out.println("catch block");
            return b += 15;
        } finally {
            System.out.println("finally block");
            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }
            b += 50;
        }
        //return b;
    }
}

console:

try block
catch block
finally block
b>25, b = 35
35
View Code

 

 

总结:还是例1前面的一句话:

finally语句在return执行之后,return返回之前执行

posted @ 2019-08-16 11:23  沦为旧友  阅读(5246)  评论(0编辑  收藏  举报