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也是操作这块内存,如果是基本类型,则直

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




  • 相关阅读:
    MIME协议(一) -- RFC822邮件格式
    生活
    面向对象设计的SOLID原则、迪米特法则
    策略模式
    asp.net Json序列化
    简单工厂模式
    CSS响应式布局实例
    CSS响应式网站开发
    mysql 记录根据日期字段倒序输出
    IE下JS保存图片
  • 原文地址:https://www.cnblogs.com/marcotan/p/4256903.html
Copyright © 2011-2022 走看看