我们都知道,在Java中try、catch和finally常用来做异常处理,而且他们有执行顺序,即先执行try,如果try中没有异常,则执行完try语句块后执行finally语句块,如果try中有异常,则顺序为执行到try语句块抛异常的地方后跳到catch语句块,最后执行fianlly语句块,但是当try、catch、finally中加入return之后,情况就有不同了,我们下面分别结合常见面试题来说明一下。
我们结合下面的程序,看看最终getInt()=?
public static void main(String[] args) {
System.out.println("getInt()=" + getInt());
}
public static int getInt() {
int a = 10;
try {
System.out.println(a / 0);
a = 20;
} catch (ArithmeticException e) {
a = 30;
System.out.println("走到catch,a=" + a);
return a;
} finally {
System.out.println("走到finally,a=" + a);
a = 40;
System.out.println("走到finally,a=" + a);
}
System.out.println("走到最后a=" + a);
return a;
}
我们分析下执行顺序,0肯定不能为除数,所以直接抛异常调到catch语句块,先输出:走到catch,a=30
然后直接return a,程序执行到这一步的时候,形成返回路径,return 30
然后发现finally语句块,所以肯定要执行finally语句块的,先是输出:走到finally,a=30,再然后输出:走到finally,a=40
到此,程序执行结束,所以最终getInt()=30
因为catch语句块里已经return a形成返回路径,所以最后两句话不会执行。
如果我们注释掉catch语句块的return a,那么程序最后两句肯定执行(因为没有return),所以最终getInt()=40
如果我们注释掉catch语句块的return a,注释程序最后两句,在fianlly语句块里加return a,那么最终getInt()=40
下面我们结合String来说明,看看最终Stringget()=?
public static void main(String[] args) {
System.out.println("Stringget()=" + Stringget());
}
public static String Stringget() {
String a = "我最喜欢胡歌";
try {
System.out.println("try……我最喜欢的电视剧是《仙剑奇侠传一》");
return a;
} catch (Exception e) {
System.out.println("catch……我最喜欢的歌曲是《逍遥叹》");
} finally {
a = a + " 并且我最喜欢的书籍是《山海经密码》";
System.out.println("finally……我说完咯");
}
return a;
}
首先,执行try语句块,输出:try……我最喜欢的电视剧是《仙剑奇侠传一》
因为程序不抛异常,所以不会执行catch语句块,所以直接执行finally语句块,输出:finally……我说完咯
因为try语句块里已经return,此时a这个String对象为我最喜欢胡歌,所以最终Stringget()=我最喜欢胡歌
如果我们把最后的return a加到fianlly语句块里:
当finally中有return的时候,try中的return会失效,在执行完finally的return之后,就不会再执行try中的return。这种写法,可以编译通过的,但是编译器会给予警告,所以不推荐在finally中写return,这会破坏程序的完整性,而且一旦finally里出现异常,会导致catch中的异常被覆盖。
总结:
1、finally中的代码总会被执行。
2、当try、catch中有return时,也会执行finally,但要注意return的返回值类型,是否受到finally中代码的影响。
3、finally中有return时,会直接在finally中退出,导致try、catch中的return失效。