Java throws和throw
throws 聲明異常
當一個方法產生一個它不處理的異常時,那么就需要在該方法的頭部聲明這個異常,以便將該異常傳遞到方法的外部進行處理。使用 throws 聲明的方法表示此方法不處理異常。throws 具體格式如下:
returnType method_name(paramList) throws Exception 1,Exception2,…{…}其中,returnType 表示返回值類型;method_name 表示方法名;paramList 表示參數列表;Exception 1,Exception2,… 表示異常類。
如果有多個異常類,它們之間用逗號分隔。這些異常類可以是方法中調用了可能拋出異常的方法而產生的異常,也可以是方法體中生成并拋出的異常。
使用 throws 聲明拋出異常的思路是,當前方法不知道如何處理這種類型的異常,該異常應該由向上一級的調用者處理;如果 main 方法也不知道如何處理這種類型的異常,也可以使用 throws 聲明拋出異常,該異常將交給 JVM 處理。JVM 對異常的處理方法是,打印異常的跟蹤棧信息,并中止程序運行。
創建一個 readFile() 方法,該方法用于讀取文件內容,在讀取的過程中可能會產生 IOException 異常,但是在該方法中不做任何的處理,而將可能發生的異常交給調用者處理。在 main() 方法中使用 try catch 捕獲異常,并輸出異常信息。代碼如下:
import java.io.FileInputStream; import java.io.IOException;public class Test {public void readFile() throws IOException {// 定義方法時聲明異常FileInputStream file = new FileInputStream("read.txt"); // 創建 FileInputStream 實例對象int f;while ((f = file.read()) != -1) {System.out.println((char) f);f = file.read();}file.close();}public static void main(String[] args) {Throws t = new Test();try {t.readFile(); // 調用 readFHe()方法} catch (IOException e) {// 捕獲異常System.out.println(e);}} }以上代碼,首先在定義 readFile() 方法時用 throws 關鍵字聲明在該方法中可能產生的異常,然后在 main() 方法中調用 readFile() 方法,并使用 catch 語句捕獲產生的異常。
方法重寫時聲明拋出異常的限制
使用 throws 聲明拋出異常時有一個限制,是方法重寫中的一條規則:子類方法聲明拋出的異常類型應該是父類方法聲明拋出的異常類型的子類或相同,子類方法聲明拋出的異常不允許比父類方法聲明拋出的異常多。看如下程序。
上面程序中 Sub 子類中的 test() 方法聲明拋出 Exception,該 Exception 是其父類聲明拋出異常 IOException 類的父類,這將導致程序無法通過編譯。
所以在編寫類繼承代碼時要注意,子類在重寫父類帶 throws 子句的方法時,子類方法聲明中的 throws 子句不能出現父類對應方法的 throws 子句中沒有的異常類型,因此 throws 子句可以限制子類的行為。也就是說,子類方法拋出的異常不能超過父類定義的范圍。
throw 拋出異常
與 throws 不同的是,throw 語句用來直接拋出一個異常,后接一個可拋出的異常類對象,其語法格式如下:
throw ExceptionObject;其中,ExceptionObject 必須是 Throwable 類或其子類的對象。如果是自定義異常類,也必須是 Throwable 的直接或間接子類。例如,以下語句在編譯時將會產生語法錯誤:
throw new String("拋出異常"); // String類不是Throwable類的子類當 throw 語句執行時,它后面的語句將不執行,此時程序轉向調用者程序,尋找與之相匹配的 catch 語句,執行相應的異常處理程序。如果沒有找到相匹配的 catch 語句,則再轉向上一層的調用程序。這樣逐層向上,直到最外層的異常處理程序終止程序并打印出調用棧情況。
throw 關鍵字不會單獨使用,它的使用完全符合異常的處理機制,但是,一般來講用戶都在避免異常的產生,所以不會手工拋出一個新的異常類的實例,而往往會拋出程序中已經產生的異常類的實例。
在某倉庫管理系統中,要求管理員的用戶名需要由 8 位以上的字母或者數字組成,不能含有其他的字符。當長度在 8 位以下時拋出異常,并顯示異常信息;當字符含有非字母或者數字時,同樣拋出異常,顯示異常信息。代碼如下:
import java.util.Scanner;public class Test {public boolean validateUserName(String username) {boolean con = false;if (username.length() > 8) {// 判斷用戶名長度是否大于8位for (int i = 0; i < username.length(); i++) {char ch = username.charAt(i); // 獲取每一位字符if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {con = true;} else {con = false;throw new IllegalArgumentException("用戶名只能由字母和數字組成!");}}} else {throw new IllegalArgumentException("用戶名長度必須大于 8 位!");}return con;}public static void main(String[] args) {Test te = new Test();Scanner input = new Scanner(System.in);System.out.println("請輸入用戶名:");String username = input.next();try {boolean con = te.validateUserName(username);if (con) {System.out.println("用戶名輸入正確!");}} catch (IllegalArgumentException e) {System.out.println(e);}} }如上述代碼,在 validateUserName() 方法中兩處拋出了 IllegalArgumentException 異常,即當用戶名字符含有非字母或者數字以及長度不夠 8 位時。在 main() 方法中,調用了 validateUserName() 方法,并使用 catch 語句捕獲該方法可能拋出的異常。
運行程序,當用戶輸入的用戶名包含非字母或者數字的字符時,程序輸出異常信息,如下所示。
請輸入用戶名: admqanistrator@# java.lang.IllegalArgumentException: 用戶名只能由字母和數字組成!當用戶輸入的用戶名長度不夠 8 位時,程序同樣會輸出異常信息,如下所示。
請輸入用戶名: admin java.lang.IllegalArgumentException: 用戶名長度必須大于 8 位!throws 關鍵字和 throw 關鍵字在使用上的幾點區別如下:
1 . throws 用來聲明一個方法可能拋出的所有異常信息,表示出現異常的一種可能性,但并不一定會發生這些異常;throw 則是指拋出的一個具體的異常類型,執行 throw 則一定拋出了某種異常對象。
2 . 通常在一個方法(類)的聲明處通過 throws 聲明方法(類)可能拋出的異常信息,而在方法(類)內部通過 throw 聲明一個具體的異常信息。
3 . throws 通常不用顯示地捕獲異常,可由系統自動將所有捕獲的異常信息拋給上級方法; throw 則需要用戶自己捕獲相關的異常,而后再對其進行相關包裝,最后將包裝后的異常信息拋出。
總結
以上是生活随笔為你收集整理的Java throws和throw的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 集合中存在多种数据类型
- 下一篇: Java 栈的存储过程