在不报异常的情况下
- 如果三者都有返回值,执行代码的顺序为try->finally,以finally中的返回值为准;
- 如果只有try和catch有返回值,执行代码的顺序为try->finally,注意,这其中,对于基本类型,会先暂时保存try中需要return的信息,然后执行finally中的代码,最后返回try里的返回值(即使finally中的代码对try中的变量做更新操作也不会影响到try的return),如例1;而对于引用类型,由于存的是地址,finally中如果做了更新操作就会影响到try中的对象,如例2.
例1:
private int testReturn1() {
int i = 1;
try {
i++;
System.out.println("try:" + i);
return i;
} catch (Exception e) {
i++;
System.out.println("catch:" + i);
} finally {
i++;
System.out.println("finally:" + i);
}
return i;
}
例2:
private List<Integer> testReturn2() {
List<Integer> list = new ArrayList<>();
try {
list.add(1);
System.out.println("try:" + list);
return list;
} catch (Exception e) {
list.add(2);
System.out.println("catch:" + list);
} finally {
list.add(3);
System.out.println("finally:" + list);
}
return list;
}
在报异常的情况下
- 如果三者都有返回值,执行代码顺序为try->catch->finally,以finally中的返回值为准;
- 如果只有try和catch有返回值,执行代码顺序为try->catch->finally,然后再返回catch里的返回值,同没有报异常的情况一样,对于基本类型,finally中做更新操作不会影响到catch的return值;对于引用类型则相反。
总结:finally中有return时,会直接在finally中退出,导致try、catch中的return失效。finally中写return编译器是可以编译过的,但是会给予警告,因为这样写会破坏程序的完整性,而且一旦finally中出现异常,会覆盖catch里的异常。