Try-Catch-Finally

Java 虚拟机会把 finally 语句块作为 subroutine(对于这个 subroutine 不知该如何翻译为好,干脆就不翻译了,免得产生歧义和误解。)直接插入到 try 语句块或者 catch 语句块的控制转移语句之前。但是,还有另外一个不可忽视的因素,那就是在执行 subroutine(也就是 finally 语句块)之前,try 或者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待 subroutine 执行完毕之后,再恢复保留的返回值到操作数栈中,然后通过 return 或者 throw 语句将其返回给该方法的调用者。

例子1

/** finally块的语句在try或catch中的return语句执行之后返回之前执行 */
public class Test1 {

    public static void main(String[] args) {
        try {

            System.out.println("try block");
            return;
        } finally {
            System.out.println("finally block");
        }

//        #######打印###################
//        try block
//        finally block
    }
}

例子2

/**finally块的语句在try或catch中的return语句执行之后返回之前执行*/
public class Test2 {
    public static void main(String[] args) {
        System.out.println("reture value of test() : " + test());
        
        
//        #######打印###################
//        try block
//        exception block
//        finally block
//        reture value of test() : 2
    }

    public static int test() {
        int i = 1;

        try {
            System.out.println("try block");
            i = 1 / 0;
            return 1;
        } catch (Exception e) {
            System.out.println("exception block");
            return 2;
        } finally {
            System.out.println("finally block");
        }
    }
}

例子3

/**finally块的语句在try或catch中的return语句执行之后返回之前执行
 * 若finally里也有return语句则覆盖try或catch中的return语句直接返回
 * */

public class Test3 {
    public static void main(String[] args) {
        System.out.println("return value of getValue(): " + getValue()); 
        
//        #######打印###################
//        return value of getValue(): 1
        
    }

    @SuppressWarnings("finally")
    public static int getValue() {
        try {
            return 0;
        } finally {
            return 1;
        }
    }
}

例子4

/**finally块的语句在try或catch中的return语句执行之后返回之前执行
 * 若finally里也有return语句则覆盖try或catch中的return语句直接返回
 * */
public class Test4 {
    public static void main(String[] args) {
        System.out.println("return value of getValue(): " + getValue()); //return value of getValue(): 1
        
        
//        #######打印###################
//        return value of getValue(): 1
    }

    public static int getValue() {
        int i = 1;
        try {
            return i;
        } finally {
            i++;
        }
    }
}

例子5

/**finally块的语句在try或catch中的return语句执行之后返回之前执行*/
public class Test5 {
    public static void main(String[] args) {
        System.out.println(test());
        
//        #######打印###################
//        try block
//        return statement
//        finally block
//        after return
    }

    public static String test() {
        try {
            System.out.println("try block");
            return test1();
        } finally {
            System.out.println("finally block");
        }
    }

    public static String test1() {
        System.out.println("return statement");
        return "after return";
    }
}

例子6

/**finally块的语句在try或catch中的return语句执行之后返回之前执行*/
public class Test6
{
    public static void main(String[] args) {
        System.out.println(getMap().get("KEY").toString());
        
//        #######打印###################
//        FINALLY
    }
     
    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; //这时候,本地局部变量表中有个零时变量保存了map的地址了,等finally块执行完后,将其压入操作数栈中返回
        }
        catch (Exception e) {
            map.put("KEY", "CATCH");
        }
        finally {
            map.put("KEY", "FINALLY");
            map = null;  //这里虽然赋值为null了,但是对返回值没有影响
        }
         
        return map;
    }
}

例子7

/**finally块的语句在try或catch中的return语句执行之后返回之前执行*/
public class Test7 {

    public static void main(String[] args) {

        System.out.println(test4());
        
//        #######打印###################
//        try block
//        catch block
//        finally block
//        b>25, b = 35
//        204
    }

    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 204;
    }

}
原文地址:https://www.cnblogs.com/moris5013/p/10710393.html