有return的时候try…catch…finally的执行顺序可以分为如下几种:
情况一
try{}…catch{}…finally{} return 正常执行
//第一种情况,正常执行
public static int test1() {
int i = 0;
try {
i++; // 执行
} catch (Exception e) {
i++;
} finally {
i++; // 执行
}
return i; // 执行并返回
}
结果返回 3
情况二
try{return}…catch{}…finally{} return,try块中有return,那么会先将try块中return的值保存到临时变量中去,随后去执行finally块中的语句,最后返回保存的值。
//第二种情况,try块中return
public static int test2() {
int i = 0;
try {
i++; // 执行
return i; // 有finally,先不执行,临时保存i的值
} catch (Exception e) {
i++;
} finally {
i++; // 执行,修改的是i的副本,随后执行try块中的return,返回临时保存的值
}
return i; //try块中已经返回,不会执行此return
}
结果返回 1
情况三
try{}…catch{return}…finally{} return,catch块中有return。
- try中没异常,则正常try,finally,最后return
- try中有异常,则try块执行到异常语句之前,随后执行catch块中的语句
//第三种情况,catch块中return
public static int test3() {
int i = 0;
try {
i++; // 执行
System.out.println(i / 0);
} catch (Exception e) {
i++; //执行
return i; // 临时保存i的值
} finally {
i++; // 执行,修改的是i的副本,随后执行try块中的return,返回临时保存的值
}
return i; // catch中return,此return不再执行
}
结果返回 2
情况四
//第四种情况,修改引用类型
public static List<Integer> test4() {
List<Integer> list = new ArrayList<>();
try {
list.add(1); //执行
return list; // 返回,临时保存,执行finally块
} catch (Exception e) {
list.add(2);
return list;
} finally {
list.add(3); // 引用类型传值传的是地址,修改的同一个对象
return list; // 仍然返回try快临时保存的对象,但是对象内容已经发生改变
}
}
结果返回[1,3]
情况五
try{}…catch{return}…finally{} return,catch块中有return。
//第五种情况,finally块中带有异常
public static int test5() {
int i = 0;
try {
i++; // 执行
System.out.println(1/0);// 出现异常执行catch块
return i;
} catch (Exception e) {
i++;
return i;// 保存临时变量,执行finally块
} finally {
i++; // 执行
return i; // 执行,修改了临时变量,返回finally块中的 i
}
}
结果返回 3
总结
- 当finally块中没有return语句时,那么程序将按照正常逻辑进行return。
- 当finally块中没有return语句时,finally中的代码不会影响try中准备返回的值或者地址值,但是地址指向的对象的内容会发生改变。比如集合。
- 当finally块中有return语句时,总是会执行finally块中的return。除非你退出虚拟机了。