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
:抛出异常后执行。