在本教程中,我們將在示例的幫助下學習使用throw和throws關(guān)鍵字進行異常處理。
在Java中,異??梢苑譃閮煞N類型:
未檢查的異常:它們不是在編譯時而是在運行時被檢查,例如:ArithmeticException,NullPointerException,ArrayIndexOutOfBoundsException,Error類下的異常等。
檢查的異常:在編譯時檢查它們。例如IOException,InterruptedException等。
請參考Java異常以詳細了解已檢查和未檢查的異常。
通常,我們不需要處理未經(jīng)檢查的異常。這是因為由于編程錯誤而發(fā)生了未經(jīng)檢查的異常。并且,糾正它們而不是處理它們是一個好習慣。
現(xiàn)在,本教程將重點介紹如何使用throw和throws處理已檢查的異常。
我們在方法聲明中使用throws關(guān)鍵字來聲明其中可能發(fā)生的異常的類型。
其語法為:
accessModifier returnType methodName() throws ExceptionType1, ExceptionType2 … { // code }
從上面的語法可以看到,我們可以用throws來聲明多個異常。
import java.io.*; class Main { public static void findFile() throws IOException { //可能產(chǎn)生IOException的代碼 File newFile=new File("test.txt"); FileInputStream stream=new FileInputStream(newFile); } public static void main(String[] args) { try{ findFile(); } catch(IOException e){ System.out.println(e); } } }
輸出結(jié)果
java.io.FileNotFoundException: test.txt (No such file or directory)
當我們運行這個程序時,如果文件test.txt不存在,F(xiàn)ileInputStream將拋出一個繼承IOException類的FileNotFoundException異常。
如果方法不處理異常,則必須在throws子句中指定該方法中可能發(fā)生的異常類型,以便調(diào)用堆棧中更高層的方法可以處理它們或使用throws關(guān)鍵字本身指定它們。
findFile()方法指定可以拋出IOException。 main()方法調(diào)用此方法并處理拋出的異常。
這是我們?nèi)绾问褂胻hrows關(guān)鍵字引發(fā)多個異常的方法。
import java.io.*; class Main { public static void findFile() throws NullPointerException, IOException, InvalidClassException { // 可能產(chǎn)生NullPointerException的代碼 … … … // 可能產(chǎn)生IOException的代碼 … … … // 可能產(chǎn)生InvalidClassException的代碼 … … … } public static void main(String[] args) { try{ findFile(); } catch(IOException e1){ System.out.println(e1.getMessage()); } catch(InvalidClassException e2){ System.out.println(e2.getMessage()); } } }
這里,findFile()方法指定它可以在其throws子句中拋出NullPointerException、IOException和InvalidClassException。
請注意,我們尚未處理NullPointerException。這是因為它是未經(jīng)檢查的異常。不必在throws子句中指定它并進行處理。
可能有幾個方法會導致異常。為每種方法編寫try...catch將是乏味的,并且代碼將變得冗長且難以理解。
當您已檢查了不希望在當前方法中捕獲的異常(必須處理的異常)時,throws也很有用。
throw關(guān)鍵字用于顯式地拋出一個異常。
當引發(fā)異常時,程序執(zhí)行的流程從try塊轉(zhuǎn)移到catch塊。我們在方法中使用throw關(guān)鍵字。
其語法為:
throw throwableObject;
Throwable對象是Throwable類或Throwable類的子類的實例。
class Main { public static void divideByZero() { throw new ArithmeticException("試圖除以0"); } public static void main(String[] args) { divideByZero(); } }
輸出結(jié)果
Exception in thread "main" java.lang.ArithmeticException: 試圖除以0 at Main.divideByZero(Main.java:3) at Main.main(Main.java:7) exit status 1
在此示例中,我們明確拋出 ArithmeticException.
注意: ArithmeticException是未經(jīng)檢查的異常。通常沒有必要處理未經(jīng)檢查的異常。
import java.io.*; class Main { public static void findFile() throws IOException { throw new IOException("文件未找到"); } public static void main(String[] args) { try { findFile(); System.out.println("try塊中的其余代碼"); } catch (IOException e) { System.out.println(e.getMessage()); } } }
輸出結(jié)果
文件未找到
findFile()方法使用傳遞給其構(gòu)造函數(shù)的消息拋出一個IOException。
注意,由于它是一個檢查的異常,因此必須在throws子句中指定它。
調(diào)用findFile()方法的方法需要處理此異常,或者自己使用throws關(guān)鍵字指定它。
我們已經(jīng)在main()方法中處理了此異常。引發(fā)異常時,程序執(zhí)行的流程在try塊之間轉(zhuǎn)移到catch。因此,將跳過該try塊中的其余代碼,并執(zhí)行該catch塊中的語句。