最近在准备面试,其中设计到try,catch,finally的执行顺序有点混乱,特此查询资料
参考:http://blog.youkuaiyun.com/wangqingbo0829/article/details/52458283
参考:http://blog.youkuaiyun.com/kavensu/article/details/8067850
1、先来个例子:
public class TryTest {
/**
* 主要方法
*/
public static void main(String[] args) {
// 调用 测试方法
String result = get();
// 打印 测试方法返回的结果
System.out.println(result);
}
@SuppressWarnings({ "finally", "unused" })
public static String get(){
int value = 0;
try {
System.out.println("try……");
//等式1/0 :分母为0 的明显错误 ——制造错误(用于抛异常)
int result = 1 / value;
return "111";
} catch (Exception e) {
System.out.println("catch……");
return "444";
} finally {
System.out.println("finally……");
return "333";
}
// return "222";
}
运行结果:
(1)在通过编译器的检查后,如果finally中有return,则以finally中的return为准,其他的都将失效,return之前的代码都有效。
(2)最后一个return“222”于catch、finally中的任何一个return互斥,也就是说,在catch,finally中任何一个地方存在return,编译器就能检查,已符合返回要求
(3)catch和finally中,可同时存在return,编译能通过,但是程序中以finally中的return“333”为准,不理睬catch中的return“444”,catch中return之前的代码仍然生效。
2、程序中try内部没有异常的情况,若有finally且finally中没有return,若在try中遇到return,先跳去执行finally中的代码,在回来执行try中的return。
public class TryTest {
/**
* 主要方法
*/
public static void main(String[] args) {
// 调用 测试方法
String result = get();
// 打印 测试方法返回的结果
System.out.println(result);
}
public static String get(){
try {
System.out.println("try……");
return "111";
} catch (Exception e) {
System.out.println("catch……");
} finally {
System.out.println("finally……");
}
return "222";
}
}
运行结果为:
上面的程序不会执行try.....catch....finally之外的return,即打印的是“111”而不打印222
3、总结:
1)不管有没有异常出现,finally块中代码都会执行
2)当try和catch中有return时,finally仍然会执行
3)finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,依然是之前保存的值,所以函数返回值是在finally执行前确定的。)
4)finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
4、例子总结:
情况1:try{} catch(){}finally{} return;
显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,最后执行try中return;
finally块之后的语句return,因为程序在try中已经return所以不再执行。
情况3:try{ } catch(){return;} finally{} return;
程序先执行try,如果遇到异常执行catch块,
有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
最后执行catch块中return. finally之后也就是4处的代码不再执行。
无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
程序执行catch块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。
最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。
!!!!!自己动手实现!!!
public class test1 {
public static void main(String[] args) {
System.out.println(find());
}
public static int find(){
int a;
try{
a=3;
System.out.println("try---a--");
return a;
}catch(Exception e){
a=4;
System.out.println("catch---a");
return a;
}finally {
a=5;
System.out.println("finally---b");
return a;
}
}
}
运行结果:
try---a--
finally---b5