在調整一個項目功能的時候,需要在現有的代碼邏輯上做改動,現有功能的邏輯是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