try-catch-finally

前言:
java 中的異常處理機制你真的理解了嗎?掌握了嗎?
catch 體裏遇到 return 是怎麼處理? finally 體遇到 return 怎麼辦?finally 體裏有 System.exit() 方法怎麼處理?當 catch 和 finally 體裏同時遇上 return 怎麼辦?

相信你在處理異常的時候不是每次都把它 throws 掉就完事了,很多時候異常是需要我們自己來 catch 並針對所拋出的 Exception 做一些後續的處理工作。

直接上代碼,先貼下面測試需要調用的方法:
 1
 2    // catch 後續處理工作
 3    public static boolean catchMethod() {
 4        System.out.print("call catchMethod and return  --->>  ");
 5        return false;
 6    }

 7    // finally後續處理工作
 8    public static void finallyMethod() {
 9        System.out.println();
10        System.out.print("call finallyMethod and do something  --->>  ");
11    }

12


1. 拋出 Exception,沒有 finally,當 catch 遇上 return
 1
 2public static boolean catchTest() {
 3        try {
 4            int i = 10 / 0;   // 拋出 Exception,後續處理被拒絕
 5            System.out.println("i vaule is : " + i);
 6            return true;    // Exception 已經拋出,沒有獲得被執行的機會
 7        }
 catch (Exception e) {
 8            System.out.println(" -- Exception --");
 9            return catchMethod();    // Exception 拋出,獲得了調用方法並返回方法值的機會
10        }

11    }

12

後臺輸出結果:
1
2 -- Exception --
3call catchMethod and return  --->>  false
4

2. 拋出 Exception,當 catch 體裏有 return,finally 體的代碼塊將在 catch 執行 return 之前被執行
 1
 2public static boolean catchFinallyTest1() {
 3        try {
 4            int i = 10 / 0; // 拋出 Exception,後續處理被拒絕
 5            System.out.println("i vaule is : " + i);
 6            return true;   // Exception 已經拋出,沒有獲得被執行的機會
 7        }
 catch (Exception e) {
 8            System.out.println(" -- Exception --");
 9            return catchMethod();  // Exception 拋出,獲得了調用方法的機會,但方法值在 finally 執行完後才返回
10        }
finally{
11            finallyMethod();  // Exception 拋出,finally 代碼塊將在 catch 執行 return 之前被執行
12        }

13    }

14

後臺輸出結果:
1
2 -- Exception --
3call catchMethod and return  --->>  
4call finallyMethod and do something  --->>  false
5


2‘. 拋出Exception,當catch裏面有throw e, finally體的代碼塊將在catch執行throw之前被執行。(經過測試)


3. 不拋 Exception,當 finally 代碼塊裏面遇上 return,finally 執行完後將結束整個方法
 1
 2public static boolean catchFinallyTest2() {
 3        try {
 4            int i = 10 / 2;  // 不拋出 Exception
 5            System.out.println("i vaule is : " + i);
 6            return true;   // 獲得被執行的機會,但執行需要在 finally 執行完成之後才能被執行
 7        }
 catch (Exception e) {
 8            System.out.println(" -- Exception --");
 9            return catchMethod();
10        }
finally{
11            finallyMethod();
12            return false// finally 中含有 return 語句,這個 return 將結束這個方法,不會在執行完之後再跳回 try 或 catch 繼續執行,方法到此結束,返回 false
13        }

14    }

15

後臺輸出結果:
1
2i vaule is : 5
3
4call finallyMethod and do something  --->>  false
5

4. 不拋 Exception,當 finally 代碼塊裏面遇上 System.exit() 方法 將結束和終止整個程序,而不只是方法
 1
 2public static boolean finallyExitTest() {
 3        try {
 4            int i = 10 / 2;  // 不拋出 Exception
 5            System.out.println("i vaule is : " + i);
 6            return true;   // 獲得被執行的機會,但由於 finally 已經終止程序,返回值沒有機會被返回
 7        }
 catch (Exception e) {
 8            System.out.println(" -- Exception --");
 9            return true;
10        }
finally {
11            finallyMethod();
12            System.exit(0);// finally 中含有 System.exit() 語句,System.exit() 將退出整個程序,程序將被終止
13        }

14    }

15

後臺輸出結果:
1
2i vaule is : 5
3
4call finallyMethod and do something  --->>  
5

5. 拋出 Exception,當 catch 和 finally 同時遇上 return,catch 的 return 返回值將不會被返回,finally 的 return 語句將結束整個方法並返回
 1
 2public static boolean finallyTest1() {
 3        try {
 4            int i = 10 / 0; // 拋出 Exception,後續處理被拒絕
 5            System.out.println("i vaule is : " + i);
 6            return true;   // Exception 已經拋出,沒有獲得被執行的機會
 7        }
 catch (Exception e) {
 8            System.out.println(" -- Exception --");
 9            return true;  // Exception 已經拋出,獲得被執行的機會,但返回操作將被 finally 截斷
10        }
finally {
11            finallyMethod();
12            return false;  // return 將結束整個方法,返回 false
13        }

14    }

15

後臺輸出結果:
1
2 -- Exception --
3
4call finallyMethod and do something  --->>  false
5

6. 不拋出 Exception,當 finally 遇上 return,try 的 return 返回值將不會被返回,finally 的 return 語句將結束整個方法並返回
 1
 2public static boolean finallyTest2() {
 3        try {
 4            int i = 10 / 2;  // 不拋出 Exception
 5            System.out.println("i vaule is : " + i);
 6            return true;   // 獲得被執行的機會,但返回將被 finally 截斷
 7        }
 catch (Exception e) {
 8            System.out.println(" -- Exception --");
 9            return true;
10        }
finally {
11            finallyMethod();
12            return false// return 將結束這個方法,不會在執行完之後再跳回 try 或 catch 繼續執行,返回 false
13        }

14    }

15

後臺輸出結果:
1
2i vaule is : 5
3
4call finallyMethod and do something  --->>  false
5
結語:
(假設方法需要返回值)
java 的異常處理中,
在不拋出異常的情況下,程序執行完 try 裏面的代碼塊之後,該方法並不會立即結束,而是繼續試圖去尋找該方法有沒有 finally 的代碼塊,
如果沒有 finally 代碼塊,整個方法在執行完 try 代碼塊後返回相應的值來結束整個方法;
如果有 finally 代碼塊,此時程序執行到 try 代碼塊裏的 return 語句之時並不會立即執行 return,而是先去執行 finally 代碼塊裏的代碼,
若 finally 代碼塊裏沒有 return 或沒有能夠終止程序的代碼,程序將在執行完 finally 代碼塊代碼之後再返回 try 代碼塊執行 return 語句來結束整個方法;
若 finally 代碼塊裏有 return 或含有能夠終止程序的代碼,方法將在執行完 finally 之後被結束,不再跳回 try 代碼塊執行 return。

在拋出異常的情況下,原理也是和上面的一樣的,你把上面說到的 try 換成 catch 去理解就 OK 了 *_*


exception有以下幾個最主要的屬性值:message - the detail message.你想傳遞給用戶的一些信息,它是一個字符串類型,你可以寫任何你想寫的message。cause - the cause. (A null value is permitted, and indicates that the cause is nonexistent or unknown.)enableSuppression - whether or not suppression is enabled or disabled

writableStackTrace - whether or not the stack trace should be writable


The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement. Similarly, only this class or one of its subclasses can be the argument type in a catch clause. For the purposes of compile-time checking of exceptions, Throwable and any subclass of Throwable that is not also a subclass of either RuntimeException or Error are regarded as checked exceptions.

Throwable是所有error和exception的父類,只有這種類型的對象實例才能被jvm的throw子句拋出,同樣的也只有這樣類型的子句才能夠被catch子句獲得。可以通過throwable來獲得線程運行過程中產生的非正常錯誤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章