在调整一个项目功能的时候,需要在现有的代码逻辑上做改动,现有功能的逻辑是try-catch 异常后在catch中打印了日志,后需将异常throw出来
我增加的逻辑中需要增加 finally操作,那么这个throw操作和finally操作的顺序是什么样的呢, 增加了finally后会影响throw出异常吗,所以就针对这块做了写测试
(1)没有return,没有异常的场景
public class ExceptionTest { static void testEx01() throws Exception { try { System.out.println("testEx,successfully"); } catch (Exception e) { System.out.println("testEx, catch exception"); throw e; } finally { System.out.println("testEx, finally"); } } public static void main(String[] args) throws Exception { testEx01(); } }
执行结果:
testEx,successfully testEx, finally
结论:
执行try的逻辑后,执行finally的逻辑
——————————————————————————————————————————————————————————————————————————————————————————————————————
(2)没有return值,有异常的场景
static void testEx01() throws Exception {
try {
int ret = 12/0;
System.out.println("testEx,successfully");
} catch (Exception e) {
System.out.println("testEx, catch exception");
throw e;
} finally {
System.out.println("testEx, finally");
}
}
执行结果:
testEx, catch exception testEx, finally Exception in thread "main" java.lang.ArithmeticException: / by zero at com.jd.ldop.logtools.ExceptionTest.testEx01(ExceptionTest.java:11) at com.jd.ldop.logtools.ExceptionTest.main(ExceptionTest.java:23) Process finished with exit code 1
结论:
执行catch代码的逻辑,抛出异常,执行finally的逻辑
——————————————————————————————————————————————————————————————————————————————————————————————————————
(2)有return值,没有异常的场景,finally中有return值
catch中 return 和 throw不可以同时存在,以下场景编译不通过
static int testEx01() throws Exception { try { int ret = 12/0; System.out.println("testEx,successfully"); return 111; } catch (Exception e) { System.out.println("testEx, catch exception"); throw e; return 222; } finally { System.out.println("testEx, finally"); return 333; } }
去除 catch中return
public class ExceptionTest { static int testEx01() throws Exception { try { int ret = 12 / 1; System.out.println("testEx,successfully"); return 111; } catch (Exception e) { System.out.println("testEx, catch exception"); throw e; } finally { System.out.println("testEx, finally"); return 333; } } public static void main(String[] args) throws Exception { System.out.println(testEx01()); } }
执行结果:
testEx,successfully testEx, finally 333 Process finished with exit code 0
结论:
执行try主流程逻辑,finally中有return的时候,会以finally中的return结果为准,其他的都将失效
——————————————————————————————————————————————————————————————————————————————————————————————————————
(3)有return值,有异常,finally中有return值的场景
public class ExceptionTest { static int testEx01() throws Exception { try { int ret = 12 / 0; System.out.println("testEx,successfully"); return 111; } catch (Exception e) { System.out.println("testEx, catch exception"); throw e; } finally { System.out.println("testEx, finally"); return 333; } } public static void main(String[] args) throws Exception { System.out.println(testEx01()); } }
执行结果:
testEx, catch exception testEx, finally 333 Process finished with exit code 0
结论:
从执行结果看,最终是返回了finally中的返回值,catch中代码执行了,但是异常并没有throw出来,这个异常被忽略了
——————————————————————————————————————————————————————————————————————————————————————————————————————
(4)有return值,有异常,finally中没有return值的场景
public class ExceptionTest {
static int testEx01() throws Exception {
try {
int ret = 12 / 0;
System.out.println("testEx,successfully");
return 111;
} catch (Exception e) {
System.out.println("testEx, catch exception");
throw e;
} finally {
System.out.println("testEx, finally");
}
}
public static void main(String[] args) throws Exception {
System.out.println(testEx01());
}
}
执行结果:
testEx, catch exception testEx, finally Exception in thread "main" java.lang.ArithmeticException: / by zero at com.jd.ldop.logtools.ExceptionTest.testEx01(ExceptionTest.java:11) at com.jd.ldop.logtools.ExceptionTest.main(ExceptionTest.java:24) Process finished with exit code 1
结论:
在finally没有返回值的场景中,异常会被抛出来,最终也是没有返回值的,因为运行时异常了
所以在finally中没有返回值的异常场景下,在catch代码块和finally代码块中去设置 返回变量的值是没有意义的,比如说如下:
执行结果是和上面一样的:
testEx, catch exception testEx, finally Exception in thread "main" java.lang.ArithmeticException: / by zero at com.jd.ldop.logtools.ExceptionTest.testEx01(ExceptionTest.java:12) at com.jd.ldop.logtools.ExceptionTest.main(ExceptionTest.java:27) Process finished with exit code 1