首先,finally不会影响代码的执行顺序(即还是顺序执行的)。
1. finally在return之前,finally做的修改会影响函数的返回结果;
/**
* @author yhcookie
* @date 2019/9/9 15:54
*/
public class TestFinally {
static int a = 1;
public static void main(String[] args){
System.out.println("testFinally在finally执行之后返回时,返回值为" + testFinally());
System.out.println("最终a的值为: " + a);
}
private static int testFinally(){
try{
System.out.println("try中a的值为:" + ++a);
return a;
}catch(Exception e){
e.printStackTrace();
}finally{
System.out.println("finally中a的值为" + ++a);
}
// 由于代码时顺序执行,此时finally中值的改变会影响返回值。
return a;
}
}
console:
try中a的值为:2
finally中a的值为3
testFinally在finally执行之后返回时,返回值为3
最终a的值为: 3
2. finally在return之后,jvm会把return的结果保存一份,再执行finally,此时分两种情况:
情形一:return结果为基本数据类型时,finally修改的结果不会影响return的结果,但是会影响所操作变量的值;
/**
* @author yhcookie
* @date 2019/9/9 15:54
*/
public class TestFinally {
static int a = 1;
public static void main(String[] args){
System.out.println("testFinally在finally执行之前返回时,返回值为" + testFinally());
System.out.println("最终a的值为: " + a);
}
private static int testFinally(){
try{
System.out.println("try中a的值为:" + ++a);
return a;
}catch(Exception e){
e.printStackTrace();
}finally{
System.out.println("finally中a的值为" + ++a);
}
return 0;
}
}
console:
try中a的值为:2
finally中a的值为3
testFinally在finally执行之前返回时,返回值为2
最终a的值为: 3
情形二:return结果为引用类型时,finally修改的结果会影响return的结果。
/**
* @author yhcookie
* @date 2019/9/9 15:54
*/
public class TestFinally {
static List<Integer> a = new ArrayList();
public static void main(String[] args){
a.add(1);
System.out.println("testFinally在finally执行之前返回时,返回值为" + testFinally());
System.out.println("最终a的值为: " + a);
}
private static List<Integer> testFinally(){
try{
a.add(2);
System.out.println("try中a的值为:" + a);
return a;
}catch(Exception e){
e.printStackTrace();
}finally{
a.add(3);
System.out.println("finally中a的值为" + a);
}
return a;
}
}
console:
try中a的值为:[1, 2]
finally中a的值为[1, 2, 3]
testFinally在finally执行之前返回时,返回值为[1, 2, 3]
最终a的值为: [1, 2, 3]
因为return返回的是在栈中的值,基本数据类型存在栈中,对他的修改会直接影响这个值;而引用数据类型实际存在堆中,栈中存的是他的引用。所以基本数据类型时,finally中修改后的值和jvm在return后保存的值是不同的,而引用是同一个。
3.finally中有return时,会覆盖掉之前的return,且finally之后不能再return了(编译器检查)。