zoukankan      html  css  js  c++  java
  • try与finally返回结果执行先后详解

    先看一段代码:

    @Test
    	public void test1(){
    		System.out.println(testf1());
    	}
    	
    	int testf1()  
        {  
            int x = 1;  
            try  
            {  
                return x;  
            }  
            finally  
            {  
                ++x;  
                System.out.println(x);
            }  
        }  

    执行结果:----------------------------

    2

    1

    为什么最后的返回结果不是2呢?明明finally已经对x+1的运行已经执行了才返回。

    讲上面程序修改下,在finally块里也加上return。

           @Test
    	public void test2(){
    		System.out.println(testf2());
    	}
    	
    	int testf2()  
        {  
            int x = 1;  
            try  
            {  
                return x;  
            }  
            finally  
            {  
                ++x;  
                System.out.println(x);
                return x;
            }  
        }  

    返回结果:------------------------

    2

    2

    很奇怪,改完之后输出结果变成了2。

    再将程序修改下:

    @Test
    	public void test3(){
    		System.out.println(test8());
    	}
    	
    	public int test8(){
    		try{
    			return f1();
    		}finally{
    			return f2();
    		}
    	}
    	
    	public int f1(){
    		System.out.println("f1");
    		return 1;
    	}
    	
    	public int f2(){
    		System.out.println("f2");
    		return 2;
    	}

    执行结果:--------------------------

    f1
    f2
    2
    
    结果中可发现是在try块里的return语句先执行,但执行了return之后,子函数并没有立即返回,而是继续执行了finally块里的语句并return。最后的返回结果采取的是

    finally块里的return结果。

    猜想:子函数在try中return时将返回结果压入栈中,而在finally中再次return时,由于返回类型是基本类型,直接覆盖了上次的返回结果。这样子函数调用返回给上层函数的结果

    就是最后一次finally中return的结果。为了验证这个猜想,继续修改程序,代码如下:

    @Test
    	public void test9(){
    		StringBuilder sb = new StringBuilder("a");
    		System.out.println(test9(sb));
    	}
    	
    	public StringBuilder test9(StringBuilder sb){
    		try{
    			return f1(sb);//先执行,将结果压入栈中
    		}finally{
    			return f2(sb);//后执行,再将前一次结果覆盖
    		}
    	}
    
    	private StringBuilder f2(StringBuilder sb) {
    		System.out.println("f2");
    		return sb.append("f2");
    	}
    
    	private StringBuilder f1(StringBuilder sb) {
    		System.out.println("f1");
    		return sb.append("f1");
    	}


    执行结果:-----------------------------------
    f1
    f2
    af1f2
    

    结果中也有try块中返回结果的f1,也有finally块中返回结果的f2。那为何与上次的实验结果不同呢,注意到这次返回类型是对象类型StringBuilder,每次return都是在原来的返回

    结果上append,而不是覆盖。这也就验证了try中return子函数并没有实际返回,而是将结果存入到一个内存中,而finally中的return也是操作这块内存,如果是基本类型,则直

    接覆盖,如果是引用类型,则根据具体的操作来决定是覆盖还是修改。




  • 相关阅读:
    Ubuntu把在任事器范围起更次要的脚色
    linux下firefox 3.0 flash失效的治理法子
    Fedora的一些根蒂设置装备摆设(三、有关Firefox的放慢设置装备摆设)
    Linux操纵零碎下即时通讯软件
    QGtkStyle 让 KDE 法式拥有 Gnome 外不雅
    Ubuntu 8.04 告白登岸德国柏林的地铁零碎
    关于linux的一些重要日记文件
    linux下挂载U盘进程
    对Fedora9的一些心得领会(另附一些末尾设置装备安插)
    使用distinct在mysql中查询多条不重复记载值的处理责罚步调
  • 原文地址:https://www.cnblogs.com/marcotan/p/4256903.html
Copyright © 2011-2022 走看看