Java 中的異常處理除了捕獲異常和處理異常之外,還包括聲明異常和拋出異常。實現(xiàn)聲明和拋出異常的關鍵字非常相似,它們是 throws 和 throw?梢酝ㄟ^ throws 關鍵字在方法上聲明該方法要拋出的異常,然后在方法內(nèi)部通過 throw 拋出異常對象。本節(jié)詳細介紹在 Java 中如何聲明異常和拋出異常。
throws 聲明異常
當一個方法產(chǎn)生一個它不處理的異常時,那么就需要在該方法的頭部聲明這個異常,以便將該異常傳遞到方法的外部進行處理。使用 throws 聲明的方法表示此方法不處理異常。throws 具體格式如下:
returnType method_name(paramList) throws Exception 1,Exception2,…{…}
其中,returnType 表示返回值類型;method_name 表示方法名;paramList 表示參數(shù)列表;Exception 1,Exception2,… 表示異常類。
如果有多個異常類,它們之間用逗號分隔。這些異常類可以是方法中調(diào)用了可能拋出異常的方法而產(chǎn)生的異常,也可以是方法體中生成并拋出的異常。
使用 throws 聲明拋出異常的思路是,當前方法不知道如何處理這種類型的異常,該異常應該由向上一級的調(diào)用者處理;如果 main 方法也不知道如何處理這種類型的異常,也可以使用 throws 聲明拋出異常,該異常將交給 JVM 處理。JVM 對異常的處理方法是,打印異常的跟蹤棧信息,并中止程序運行,這就是前面程序在遇到異常后自動結束的原因。
例 1
創(chuàng)建一個 readFile() 方法,該方法用于讀取文件內(nèi)容,在讀取的過程中可能會產(chǎn)生 IOException 異常,但是在該方法中不做任何的處理,而將可能發(fā)生的異常交給調(diào)用者處理。在 main() 方法中使用 try catch 捕獲異常,并輸出異常信息。代碼如下:
import java.io.FileInputStream;import java.io.IOException;public class Test04 { public void readFile() throws IOException { // 定義方法時聲明異常 FileInputStream file = new FileInputStream("read.txt"); // 創(chuàng)建 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 Test04(); try { t.readFile(); // 調(diào)用 readFHe()方法 } catch (IOException e) { // 捕獲異常 System.out.println(e); } }}
以上代碼,首先在定義 readFile() 方法時用 throws 關鍵字聲明在該方法中可能產(chǎn)生的異常,然后在 main() 方法中調(diào)用 readFile() 方法,并使用 catch 語句捕獲產(chǎn)生的異常。
方法重寫時聲明拋出異常的限制
使用 throws 聲明拋出異常時有一個限制,是方法重寫中的一條規(guī)則:子類方法聲明拋出的異常類型應該是父類方法聲明拋出的異常類型的子類或相同,子類方法聲明拋出的異常不允許比父類方法聲明拋出的異常多。看如下程序。
public class OverrideThrows { public void test() throws IOException { FileInputStream fis = new FileInputStream("a.txt"); }}class Sub extends OverrideThrows { // 子類方法聲明拋出了比父類方法更大的異常 // 所以下面方法出錯 public void test() throws Exception { }}
上面程序中 Sub 子類中的 test() 方法聲明拋出 Exception,該 Exception 是其父類聲明拋出異常 IOException 類的父類,這將導致程序無法通過編譯。
填寫下面表單即可預約申請免費試聽java課程!害怕學不會?助教陪讀,隨時解惑!擔心就業(yè)?一地學習,可全國推薦就業(yè)!
所以在編寫類繼承代碼時要注意,子類在重寫父類帶 throws 子句的方法時,子類方法聲明中的 throws 子句不能出現(xiàn)父類對應方法的 throws 子句中沒有的異常類型,因此 throws 子句可以限制子類的行為。也就是說,子類方法拋出的異常不能超過父類定義的范圍。
throw 拋出異常
與 throws 不同的是,throw 語句用來直接拋出一個異常,后接一個可拋出的異常類對象,其語法格式如下:
throw ExceptionObject;
其中,ExceptionObject 必 須是 Throwable 類或其子類的對象。如果是自定義異常類,也必 須是 Throwable 的直接或間接子類。例如,以下語句在編譯時將會產(chǎn)生語法錯誤:
throw new String("拋出異常"); // String類不是Throwable類的子類
當 throw 語句執(zhí)行時,它后面的語句將不執(zhí)行,此時程序轉(zhuǎn)向調(diào)用者程序,尋找與之相匹配的 catch 語句,執(zhí)行相應的異常處理程序。如果沒有找到相匹配的 catch 語句,則再轉(zhuǎn)向上一層的調(diào)用程序。這樣逐層向上,直到最外層的異常處理程序終止程序并打印出調(diào)用棧情況。
throw 關鍵字不會單獨使用,它的使用完全符合異常的處理機制,但是,一般來講用戶都在避免異常的產(chǎn)生,所以不會手工拋出一個新的異常類的實例,而往往會拋出程序中已經(jīng)產(chǎn)生的異常類的實例。
例 2
在某倉庫管理系統(tǒng)中,要求管理員的用戶名需要由 8 位以上的字母或者數(shù)字組成,不能含有其他的字符。當長度在 8 位以下時拋出異常,并顯示異常信息;當字符含有非字母或者數(shù)字時,同樣拋出異常,顯示異常信息。代碼如下:
import java.util.Scanner;public class Test05 { 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("用戶名只能由字母和數(shù)字組成!"); } } } else { throw new IllegalArgumentException("用戶名長度必 須大于 8 位!"); } return con; } public static void main(String[] args) { Test05 te = new Test05(); 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 異常,即當用戶名字符含有非字母或者數(shù)字以及長度不夠 8 位時。在 main() 方法中,調(diào)用了 validateUserName() 方法,并使用 catch 語句捕獲該方法可能拋出的異常。
運行程序,當用戶輸入的用戶名包含非字母或者數(shù)字的字符時,程序輸出異常信息,如下所示。
請輸入用戶名:
administrator@#
java.lang.IllegalArgumentException: 用戶名只能由字母和數(shù)字組成!
當用戶輸入的用戶名長度不夠 8 位時,程序同樣會輸出異常信息,如下所示。
請輸入用戶名:
admin
java.lang.IllegalArgumentException: 用戶名長度必 須大于 8 位!
throws 關鍵字和 throw 關鍵字在使用上的幾點區(qū)別如下:
throws 用來聲明一個方法可能拋出的所有異常信息,表示出現(xiàn)異常的一種可能性,但并不一定會發(fā)生這些異常;throw 則是指拋出的一個具體的異常類型,執(zhí)行 throw 則一定拋出了某種異常對象。
通常在一個方法(類)的聲明處通過 throws 聲明方法(類)可能拋出的異常信息,而在方法(類)內(nèi)部通過 throw 聲明一個具體的異常信息。
throws 通常不用顯示地捕獲異常,可由系統(tǒng)自動將所有捕獲的異常信息拋給上級方法; throw 則需要用戶自己捕獲相關的異常,而后再對其進行相關包裝,最后將包裝后的異常信息拋出。
上一篇:Java9增強的自動資源管理
下一篇: 沒有了
初級會計職稱中級會計職稱經(jīng)濟師注冊會計師證券從業(yè)銀行從業(yè)會計實操統(tǒng)計師審計師高級會計師基金從業(yè)資格稅務師資產(chǎn)評估師國際內(nèi)審師ACCA/CAT價格鑒證師統(tǒng)計資格從業(yè)
一級建造師二級建造師消防工程師造價工程師土建職稱房地產(chǎn)經(jīng)紀人公路檢測工程師建筑八大員注冊建筑師二級造價師監(jiān)理工程師咨詢工程師房地產(chǎn)估價師 城鄉(xiāng)規(guī)劃師結構工程師巖土工程師安全工程師設備監(jiān)理師環(huán)境影響評價土地登記代理公路造價師公路監(jiān)理師化工工程師暖通工程師給排水工程師計量工程師
執(zhí)業(yè)藥師執(zhí)業(yè)醫(yī)師衛(wèi)生資格考試衛(wèi)生高級職稱護士資格證初級護師主管護師住院醫(yī)師臨床執(zhí)業(yè)醫(yī)師臨床助理醫(yī)師中醫(yī)執(zhí)業(yè)醫(yī)師中醫(yī)助理醫(yī)師中西醫(yī)醫(yī)師中西醫(yī)助理口腔執(zhí)業(yè)醫(yī)師口腔助理醫(yī)師公共衛(wèi)生醫(yī)師公衛(wèi)助理醫(yī)師實踐技能內(nèi)科主治醫(yī)師外科主治醫(yī)師中醫(yī)內(nèi)科主治兒科主治醫(yī)師婦產(chǎn)科醫(yī)師西藥士/師中藥士/師臨床檢驗技師臨床醫(yī)學理論中醫(yī)理論