Ttry_catch_finally finally不惧return

关于Ttry_catch_finally自己的一些理解                          

package com.day;

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

/**
*
* @author xujiangpeng 
* @E-mail:442410707@qq.com
* @version 创建时间:2016年11月15日 下午1:53:52
* 
* 至少有两种情况下finally语句是不会被执行的:
* (1)try语句没有被执行到,如在try语句之前就返回了,这样finally语句就不会执行,
*     The finally block always executes when the try block exits.
* 
*       这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。
* (2)在try块中有System.exit(0);这样的语句,System.exit(0);
*       是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。
*   极端的情况下;
*   当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),
*   与其相对应的 finally 语句块可能不会执行。
* 
*   虽然 return、throw、break 和 continue 都是控制转移语句,但是它们之间是有区别的。
*   其中 return 和 throw 把程序控制权转交给它们的调用者(invoker),而 break 和 continue 的控制权是在当前方法内转移
*/


/**
 * Note: If the JVM exits while the try or catch code is being executed, 
 * then the finally block may not execute. Likewise,
 * if the thread executing the try or catch code is interrupted or killed, 
 * the finally block may not execute even though the application as a whole continues.
 *
 */
public class Ttry_catch_finally {

    public static void main(String[] args) {

        System.out.println(test1());
        //System.out.println(test2());
        //System.out.println(test3());

    }


    /**说明try里面的语句已经执行了,但是没有返回。
     * 所以finally语句是在try的return语句执行之后,return返回之前执行
     * b>25, b = 100
     * 100
     */
    public static int test1() {
        int b = 20;
        try {
            return b += 80; 
        }
        catch (Exception e) {

        }
        finally {
            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }
        }
        return b;
    }

    /**
     * finally中的return会提前跳出程序运行。
     * b>25, b = 100
     * 1100
     * 
     * 还有就是不推荐在finally中使用return语句会有警告
     * finally block does not complete normally
     */
    @SuppressWarnings("finally")
    public static int test2() {
        int b = 20;
        try {
            return b += 80; 
        } catch (Exception e) {

        } finally {
            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }

            return b += 1000;
        }

        //return b;
        //这里写的语句都不可到达。
    }


    /**
     * {map=xiugai}
     *  
     * 在 finally 语句块执行之前,getValue()方法保存了其返回值(1)到本地表量表中 1 的位置
     * 完成这个任务的指令是 istore_1;然后执行 finally 语句块(iinc 0, 1),finally 语句块把位于 0 这个位置的本地变量表中的值加 1,变成 2;
     * 待 finally 语句块执行完毕之后,把本地表量表中 1 的位置上值恢复到操作数栈(iload_1),
     * 最后执行 ireturn 指令把当前操作数栈中的值(1)返回给其调用者(main)。
     * 
     * 也就是说,该变量是记录过的。
     * 
     * finally操作的变量如果是基本类型的话不会影响返回值。 
     * 是引用类型的话,因为指向同一个对象所以还是有影响的。
     */
    public static Object test3() {
        Map<String, Object> xmap = new HashMap<String,Object>();
        xmap.put("map","***");
        try {
            //return xmap.get("map");
            //像上面的情况,返回的是值,所以不会被finally改变。

            return xmap;
            //返回的是引用(其实也是一个值,首地址的值,所以后面xmap = null;不起作用),
            //如果finally改变了该引用指向的栈中的对象值,这里的输出值就会变。
        } catch (Exception e) {

        } finally {

            xmap.put("map","xiugai");//不影响返回的map地址,但是会改变内容。

            xmap = null; //不会影响上面的引用。
        }

        return xmap;
    }
}

关于 Java 中 finally 语句块的深度辨析请参见如下网址:

http://www.ibm.com/developerworks/cn/java/j-lo-finally/index.html

posted @ 2017-05-15 16:49  sky20080101  阅读(80)  评论(0)    收藏  举报