作为一个程序员,大家应该经常会用到try{}catch(){}finally处理一些代码逻辑,主要是捕获代码中的异常,方便问题的跟踪,当然也是为了防止一个堆栈的抛出直接返回到方法外。
一般来说,一个方法请求的接口都是使用try{}catch(){}finally{}进行包裹,捕获方法请求中的异常,如果代码发生异常,返回接口一个错误信息,方便问题的排查。
当然一些事物或者service中也会经常用到try{}catch(){},捕获异常,捕获关闭流信息或者其他实现自己对方法的处理。今天我们就来说下try{}catch(){}finally{}中return 返回的问题。
首先,大家都知道try{}catch(){}finally{}中首先运行try结构体中的业务逻辑,如果发生异常,catch 会捕获异常,然后在方法体中完成自己对异常的处理,打印日志或者抛出异常日志都可以。然后finally中的代码一定会执行,实现最终的操作,比如:我们创建一个流,然后进行操作
FileInputStream inputStream = null;
try{
inputStream = new FileInputStream(new File(""));
// to do sth
} catch (Exception e ){
//to do sth
} finally {
if(inputStream == null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
类似这种代码大家应该见过不少,这个就是我最早见识try{}catch(){}finally{} 的应用,也会这个结构最常用的一种,一般一旦牵涉到文件的读取,都要是用try{}catch(){}finally{}包裹,防止资源的泄露。
当然这种写法没有太大的问题,不过如果牵涉到返回,一些伙伴可能就有些蒙了,比如:
try {
System.out.println(1==1);
int i = 1 / 0;
return 111;
} catch (Exception e ){
e.printStackTrace();
return 222;
} finally {
System.out.println("finally 运行了~~");
return new Integer(333);
}
比如这种,返回究竟是111、222还是333 ?就好像我们想写一个方法,try的代码块之中书写正常的操作逻辑,返回成功或者失败,catch捕获RuntimeException,然后可能想在finally中写一个捕获异常之后的返回,比如系统异常之类的。可以么?
这个,当然不可以!
如果你想返回一个系统异常的信息,可以在方法去掉finally代码块,直接在下面返回一个错误信息,或者在catch中返回也可以,但是如果在finally中写了,那每次请求返回的都是finally中的异常信息,这个方法就直接崩了。
好了,我们来具体看下try{}catch(){}finally{}中的返回,首先,没有任何异常时是如何返回的;
try {
System.out.println(1==1);
return 111;
} catch (Exception e ){
e.printStackTrace();
return 222;
} finally {
System.out.println("finally 运行了~~");
return new Integer(333);
}
运行这段代码,我们可以看到运行结果,返回的是finally代码块中的信息。
true
finally 运行了~~
结果打印:333
那么是return 111;没有执行么?不是的,return 111;肯定是执行了的,不过由于最终会执行finlly中的信息,这个111就被333代替了,所以打印的结果是333。当然如果finally中没有返回,打印的就是111了。因为没有发生异常,所以catch中的返回并不会起作用。
那如果发生了异常呢?比如:
try {
System.out.println(1==1);
int i = 3 / 0;
return 111;
} catch (Exception e ){
e.printStackTrace();
System.out.println("发生异常了!");
return 222;
} finally {
System.out.println("finally 运行了~~");
return new Integer(333);
}
我们可以看到运行结果:
true
java.lang.ArithmeticException: / by zero
at com.pindao.teacore.Test.test2(Test.java:22)
at com.pindao.teacore.Test.main(Test.java:13)
发生异常了!
finally 运行了~~
结果打印:333
发生了异常,catch捕获,然后运行代码逻辑,不过和try中一样,最后的return也被finally覆盖了,返回了结果333。如果没有finally,最终返回的就是222了。
因此我们大致可以得到结论:try{}catch(){}finally{}中,如果finally中有返回,那么try与catch中的返回最终都会被finally中的返回覆盖,起不到返回的作用,所以建议在finally中最好不要有返回。如果finally中没有返回,代码没有发生异常,那么正常返回try结构体中的return,如果发生异常,catch捕获,返回数据,或者可以在方法的最后返回一个异常的reponse。