public class Class_Demo {
public static void main(String[] args){
Class_Demo s = new Class_Demo();
int a=s.fun();
System.out.println(a);
}
int fun(){
(1)int x=5;
try{
(2) System.out.println(x/0);
return 0;
}(3):catch(ArithmeticException e){
(7)return (4)++x;
}(5)finally{
(6)x=4;
}
}
}
我们说不管try语句中有没有异常发生,都会执行finally语句,但到底是哪个语句先执行昵?上面的代码会出现一个除0异常,并被catch语句捕获,然后在catch语句中返回x的值,但此时finally语句在什么时候执行?这里我们可以将return ++x语句看成两个子语句,在try语句中发生除0异常,所以下面的return 0语句就没有执行,直接跳到catch语句中,执行return,我们前面说了,将return ++x看成两个子语句,这时首先执行得到++x的值,然后保存此值的副本在return 语句中(此时并没有返回),然后再执行finally语句中的语句,最后再执行return。虽然finally中为x赋值为4,但并不影响保存在return语句中副本的值,所以返回的是6,输出也为6。
从这可以看出,finally中的值得改变并不会影响return保存的副本的值,这就相当于函数传参,如fun(int a),假设给b=5,fun(b)你在fun函数中不管怎样修改形参a的值,都不会改变调用fun函数中的实参b的值,传递的只是b的副本而已。编号(1)(2)(3)(4)(5)(6)(7)就是fun函数中的执行顺序。
int fun(){
int a=5;
try{
System.out.println(a/0);
return 0;
}catch(ArithmeticException e){
return ++a;
}finally{
return ++a;
}
}
上述代码返回是7,也从侧面验证了我们对于第一个代码理解的正确,只不过这里返回直接在finally中返回了,以至于只执行catch语句中的++a,而没有执行catch中的return。
public class Class_Demo {
public int num;
public static void main(String[] args){
Class_Demo s = new Class_Demo();
Class_Demo a=s.fun();
System.out.println(a.num);
}
Class_Demo fun(){
Class_Demo obj = new Class_Demo();
obj.num=5;
try{
System.out.println(obj.num/0);
return obj;
}catch(ArithmeticException e){
return obj;
}
finally{
obj.num=10;
}
}
}
上述代码输出的是10,显然是返回了修改后finally中的值,这里返回的是对象,也可以说像函数传参,形参是对象,保存在return中的是对象的引用,你修改对象的成员,必然会影响返回的引用的结果。(若返回的不是基本类型,finally中都会影响最后的返回的结果)
总结一下,try语句没有异常且有返回值,与try有异常且相应被捕获的catch语句中有返回值的return语句执行顺序是一样的,都是先执行完再执行完finally语句后再在相应的return中返回(若finally中有return,则直接在finally中返回)。
finally不会被执行的情况:关闭了JVM(system.exit(0),在执行finally前断电)