我們可以在 Java 中重寫 catch 塊嗎?
描述
當一段特定方法中的程式碼丟擲異常,並使用 try-catch 對進行處理時。如果我們從另一個方法呼叫此方法,並且呼叫行包含在 try-catch 對中。現在,如何透過呼叫方法的 catch 塊來覆蓋 catch 塊。
當方法中的程式碼丟擲異常(編譯時)時,我們必須要麼使用 try-catch 對進行處理,要麼使用 throws 關鍵字將其丟擲(推遲)到呼叫方法,否則會發生編譯時錯誤。
在下面的 Java 示例中,readFile() 方法中的程式碼生成 FileNotFoundException,而我們沒有處理它。
示例
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class ExceptionExample{ public static String readFile(String path){ String data = null; Scanner sc = new Scanner(new File("E://test//sample.txt")); String input; StringBuffer sb = new StringBuffer(); sb.append(sc.next()); data = sb.toString(); return data; } public static void main(String args[]) { String path = "E://test//sample.txt"; readFile(path); } }
編譯時錯誤
編譯時,上述程式會生成以下編譯時錯誤。
ExceptionExample.java:7: error: unreported exception FileNotFoundException; must be caught or declared to be thrown Scanner sc = new Scanner(new File("E://test//sample.txt")); ^ 1 error
要解決此錯誤,我們需要使用 try-catch 對處理異常,例如:
示例
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class ExceptionExample{ public static String readFile(String path){ String data = null; try { Scanner sc = new Scanner(new File("E://test//sample.txt")); String input; StringBuffer sb = new StringBuffer(); sb.append(sc.next()); data = sb.toString(); } catch (FileNotFoundException ex) { System.out.println("exception occurred"); } return data; } public static void main(String args[]) { String path = "E://test//sample.txt"; readFile(path); } }
輸出
exception occurred
或者,使用 throws 關鍵字丟擲它。如果您這樣做,異常將被推遲到此方法的呼叫行,即錯誤現在出現在該行。
示例
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class ExceptionExample{ public static String readFile(String path)throws FileNotFoundException { String data = null; Scanner sc = new Scanner(new File("E://test//sample.txt")); String input; StringBuffer sb = new StringBuffer(); sb.append(sc.next()); data = sb.toString(); return data; } public static void main(String args[]) { String path = "E://test//sample.txt"; readFile(path); } }
編譯時錯誤
ExceptionExample.java:17: error: unreported exception FileNotFoundException; must be caught or declared to be thrown readFile(path); ^ 1 error
要解決此問題,您需要包裝呼叫行或使用 throws 關鍵字再次丟擲異常。
public static void main(String args[]) { String path = "E://test//sample.txt"; OverridingException obj = new OverridingException(); try { readFile(path); }catch(Exception ex) { System.out.println("Exception occured"); } }
也就是說,如果您在源方法(最初生成異常的方法)中使用 try-catch 對處理異常,則無需在呼叫方法中再次處理它。在兩個地方都使用 try-catch 是沒有意義的。
執行兩個 catch 塊中內容的唯一方法是重新丟擲異常。
重新丟擲異常
當異常在 catch 塊中被捕獲時,您可以使用 throw 關鍵字(用於丟擲異常物件)重新丟擲它。
重新丟擲異常時,您可以原樣丟擲相同的異常,而無需調整它,例如:
try { int result = (arr[a])/(arr[b]); System.out.println("Result of "+arr[a]+"/"+arr[b]+": "+result); } catch(ArithmeticException e) { throw e; }
或者,將其包裝在新的異常中並丟擲它。當您將捕獲的異常包裝在另一個異常中並丟擲它時,這被稱為異常鏈或異常包裝,透過這樣做,您可以調整您的異常,丟擲更高級別的異常來維護抽象。
try { int result = (arr[a])/(arr[b]); System.out.println("Result of "+arr[a]+"/"+arr[b]+": "+result); } catch(ArrayIndexOutOfBoundsException e) { throw new IndexOutOfBoundsException(); }
示例
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class ExceptionExample{ public static String readFile(String path){ String data = null; try { Scanner sc = new Scanner(new File("E://test//sample.txt")); String input; StringBuffer sb = new StringBuffer(); sb.append(sc.next()); data = sb.toString(); }catch (FileNotFoundException ex){ System.out.println("Exception occurred: source method"); throw ex; } return data; } public static void main(String args[]) { String path = "E://test//sample.txt"; try { readFile(path); }catch(Exception ex) { System.out.println("Exception occurred: calling method"); } } }
輸出
Exception occurred: source method Exception occurred: calling method
廣告