return与finally执行对返回值影响的大论战

finally块的语句在try或catch中的return语句执行之后返回之前执行,且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值;若finally里也有return语句则覆盖try或catch中的return语句直接返回。

综述

return:用于跳出当前方法,指向返回值指针(指针、指针、指针 …)。
finally:一定会执行。通常用于关闭资源。

函数返回的步骤:
先记录return指针位置,即此时返回值指针位置。
然后执行finally语句块,
然后返回return的指针位置。(至此函数执行结束)
所以return指针位置已固定,是不可改变的事实,一切能改变return指针位置所指向的内容的行为均可改变返回值。

只有以下两种情形,再没有其他的了哦!!!

其实这是一个关于值传递的问题

情形1:改变返回值变量指向的位置

返回指针的位置是不可改变的。
此种行为只是改变了返回值变量returnVal的指针位置;

public static String compute(String args) {
    
    
	String returnVal = "init block " + args;
	try {
    
    
		returnVal = "try block " + args;
		int i = 1 / 0;
		return returnVal;
	} catch (Exception e) {
    
    
		returnVal = "catch block " + args;
		return returnVal;
	} finally {
    
    
		returnVal = "finally block " + args;
		System.out.println("finally block 执行了哦...");
	}
}

public static void main(String[] args) {
    
    
	System.out.println(compute("你好世界。"));
}

情形2:改变返回值变量指向位置的内容

返回指针的位置是不可改变的。
此种行为是改变了返回值变量list的指针位置的内容;

public static List<String> compute(String args) {
    
    
	List<String> list = new ArrayList<String>();
	list.add("init block " + args);
	try {
    
    
		list.add("try block " + args);
		int i = 1 / 0;
		return list;
	} catch (Exception e) {
    
    
		list.add("catch block " + args);
		return list;
	} finally {
    
    
		list.add("finally block " + args);
		System.out.println("finally block 执行了哦...");
	}
}

public static void main(String[] args) {
    
    
	System.out.println(compute("你好世界。"));
}

后记

其实我是为了验证spring的@AfterReturning@AfterThrowing@After 三种通知的执行顺序问题,而来验证的,莫名其妙的想起来了值传递的问题。

@After:无论什么情况下都会执行(对应spring源码中该通知在finally块中)。
@AfterReturning:切点方法执行返回值后执行。
@AfterThrowing:抛出异常后执行。

猜你喜欢

转载自blog.csdn.net/Michael_lcf/article/details/122263860