1. 調試追蹤代碼:
1
2
3
4
5
6
7
8
9
10
11
|
public static void enterTryMethod() { System.out.println( "enter after try field" ); } public static void enterExceptionMethod() { System.out.println( "enter catch field" ); } public static void enterFinallyMethod() { System.out.println( "enter finally method" ); } |
2. 拋出Exception,沒有finally,當catch遇上return
1
2
3
4
5
6
7
8
9
10
11
12
|
public static int catchTest() { int res = 0 ; try { res = 10 / 0 ; // 拋出Exception,后續處理被拒絕 enterTryMethod(); return res; // Exception已經拋出,沒有獲得被執行的機會 } catch (Exception e) { enterExceptionMethod(); return 1 ; // Exception拋出,獲得了調用方法并返回方法值的機會 } } |
后臺輸出結果:
1
2
|
enter catch field 1 |
3. 拋出Exception,當catch體里有return,finally體的代碼塊將在catch執行return之前被執行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public static int catchTest() { int res = 0 ; try { res = 10 / 0 ; // 拋出Exception,后續處理被拒絕 enterTryMethod(); return res; // Exception已經拋出,沒有獲得被執行的機會 } catch (Exception e) { enterExceptionMethod(); return 1 ; // Exception拋出,獲得了調用方法并返回方法值的機會 } finally { enterFinallyMethod(); // Exception拋出,finally代碼將在catch執行return之前被執行 } } |
后臺輸出結果:
1
2
3
|
enter catch field enter finally method 1 |
4. 不拋出Exception,當finally代碼塊里面遇上return,finally執行完后將結束整個方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static int catchTest() { int res = 0 ; try { res = 10 / 2 ; // 不拋出Exception enterTryMethod(); return res; // 獲得被執行的機會,但執行需要在finally執行完成之后才能被執行 } catch (Exception e) { enterExceptionMethod(); return 1 ; } finally { enterFinallyMethod(); return 1000 ; // finally中含有return語句,這個return將結束這個方法,不會在執行完之后再跳回try或者catch繼續執行,方法到此結束 } } |
后臺輸出結果:
1
2
3
|
enter after try field enter finally method 1000 |
5. 不拋Exception,當finally代碼塊里面遇上System.exit()方法將結束和終止整個程序,而不只是方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static int catchTest() { int res = 0 ; try { res = 10 / 2 ; // 不拋出Exception enterTryMethod(); return res; // 獲得被執行的機會,但由于finally已經終止程序,返回值沒有機會被返回 } catch (Exception e) { enterExceptionMethod(); return 1 ; } finally { enterFinallyMethod(); System.exit( 0 ); // finally中含有System.exit()語句,System.exit()將退出整個程序,程序將被終止 } } |
后臺輸出結果:
1
2
|
enter after try field enter finally method |
6. 拋出Exception,當catch和finally同時遇上return,catch的return返回值將不會被返回,finally的return語句將結束整個方法并返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static int catchTest() { int res = 0 ; try { res = 10 / 0 ; // 拋出Exception,后續處理將被拒絕 enterTryMethod(); return res; // Exception已經拋出,沒有獲得被執行的機會 } catch (Exception e) { enterExceptionMethod(); return 1 ; // Exception已經拋出,獲得被執行的機會,但返回操作將被finally截斷 } finally { enterFinallyMethod(); return 10 ; // return將結束整個方法,返回值為10 } } |
后臺輸出結果:
1
2
3
|
enter catch field enter finally method 10 |
7. 不拋出Exception,當finally遇上return,try的return返回值將不會被返回,finally的return語句將結束整個方法并返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static int catchTest() { int res = 0 ; try { res = 10 / 2 ; // 不拋出Exception enterTryMethod(); return res; // 獲得執行機會,但返回將被finally截斷 } catch (Exception e) { enterExceptionMethod(); return 1 ; } finally { enterFinallyMethod(); return 10 ; // return將結束整個方法,返回值為10 } } |
后臺輸出結果:
1
2
3
|
enter after try field enter finally method 10 |
結論
Java的異常處理中,程序執行完try里面的代碼塊之后,該方法并不會立即結束,而是繼續試圖去尋找該方法有沒有finally的代碼塊
如果沒有finally代碼塊,整個方法在執行完try代碼塊后返回相應的值來結束整個方法
如果有finally代碼塊,此時程序執行到try代碼塊里的return一句之時并不會立即執行return,而是先去執行finally代碼塊里的代碼
若finally代碼塊里沒有return或沒有能夠終止程序的代碼,程序在執行完finally代碼塊代碼之后再返回try代碼塊執行return語句來結束整個方法。若 finally 代碼塊里有 return 或含有能夠終止程序的代碼,方法將在執行完 finally 之后被結束,不再跳回 try 代碼塊執行 return
在拋出異常的情況下,原理也是和上面的一樣的,你把上面說到的 try 換成 catch 去理解就OK了。