詳解Java異常處理中throw與throws關鍵字的用法區(qū)別
拋出異常
拋出異常有三種形式,一是throw,一個throws,還有一種系統自動拋異常。下面它們之間的異同。
系統自動拋異常
當程序語句出現一些邏輯錯誤、主義錯誤或類型轉換錯誤時,系統會自動拋出異常。如:
public static void main(String[] args) { int a = 5, b =0; System.out.println(5/b); //function(); }
系統會自動拋出ArithmeticException異常:
Exception in thread "main" java.lang.ArithmeticException: / by zero at test.ExceptionTest.main(ExceptionTest.java:62)
再如
public static void main(String[] args) { String s = "abc"; System.out.println(Double.parseDouble(s)); //function(); }
系統會自動拋出NumberFormatException異常:
Exception in thread "main" java.lang.NumberFormatException: For input string: "abc" at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224) at java.lang.Double.parseDouble(Double.java:510) at test.ExceptionTest.main(ExceptionTest.java:62)
throw
throw是語句拋出一個異常。
語法:throw (異常對象);
如:
throw e;
一般會用于程序出現某種邏輯時程序員主動拋出某種特定類型的異常。如:
public static void main(String[] args) { String s = "abc"; if(s.equals("abc")) { throw new NumberFormatException(); } else { System.out.println(s); } //function(); }
會拋出異常:
Exception in thread "main" java.lang.NumberFormatException at test.ExceptionTest.main(ExceptionTest.java:67)
throws
throws是方法可能拋出異常的聲明。(用在聲明方法時,表示該方法可能要拋出異常)
語法:[(修飾符)](返回值類型)(方法名)([參數列表])[throws(異常類)]{......}
如:
public void function() throws Exception{......}
當某個方法可能會拋出某種異常時用于throws 聲明可能拋出的異常,然后交給上層調用它的方法程序處理。如:
public static void function() throws NumberFormatException{ String s = "abc"; System.out.println(Double.parseDouble(s)); } public static void main(String[] args) { try { function(); } catch (NumberFormatException e) { System.err.println("非數據類型不能轉換。"); //e.printStackTrace(); } }
處理結果如下:
非數據類型不能轉換。
throw與throws的比較
1、throws出現在方法函數頭;而throw出現在函數體。
2、throws表示出現異常的一種可能性,并不一定會發(fā)生這些異常;throw則是拋出了異常,執(zhí)行throw則一定拋出了某種異常對象。
3、兩者都是消極處理異常的方式(這里的消極并不是說這種方式不好),只是拋出或者可能拋出異常,但是不會由函數去處理異常,真正的處理異常由函數的上層調用處理。
好的編程習慣:
1.在寫程序時,對可能會出現異常的部分通常要用try{...}catch{...}去捕捉它并對它進行處理;
2.用try{...}catch{...}捕捉了異常之后一定要對在catch{...}中對其進行處理,那怕是最簡單的一句輸出語句,或棧輸入e.printStackTrace();
3.如果是捕捉IO輸入輸出流中的異常,一定要在try{...}catch{...}后加finally{...}把輸入輸出流關閉;
4.如果在函數體內用throw拋出了某種異常,最好要在函數名中加throws拋異常聲明,然后交給調用它的上層函數進行處理。
舉例:
throws E1,E2,E3只是告訴程序這個方法可能會拋出這些異常,方法的調用者可能要處理這些異常,而這些異常E1,E2,E3可能是該函數體產生的。
throw則是明確了這個地方要拋出這個異常。
如:
void doA(int a) throws IOException,{ try{ ...... }catch(Exception1 e){ throw e; }catch(Exception2 e){ System.out.println("出錯了!"); } if(a!=b) throw new Exception3("自定義異常"); }
代碼塊中可能會產生3個異常,(Exception1,Exception2,Exception3)。
如果產生Exception1異常,則捕獲之后再拋出,由該方法的調用者去處理。
如果產生Exception2異常,則該方法自己處理了(即System.out.println("出錯了!");)。所以該方法就不會再向外拋出Exception2異常了,void doA() throws Exception1,Exception3 里面的Exception2也就不用寫了。
而Exception3異常是該方法的某段邏輯出錯,程序員自己做了處理,在該段邏輯錯誤的情況下拋出異常Exception3,則該方法的調用者也要處理此異常。
throw語句用在方法體內,表示拋出異常,由方法體內的語句處理。
throws語句用在方法聲明后面,表示再拋出異常,由該方法的調用者來處理。
throws主要是聲明這個方法會拋出這種類型的異常,使它的調用者知道要捕獲這個異常。
throw是具體向外拋異常的動作,所以它是拋出一個異常實例。
throws說明你有那個可能,傾向。
throw的話,那就是你把那個傾向變成真實的了。
如果是系統異常的話可以什么都不用做,也可以針對方法拋出一個異常,因為系統異常是可以被系統自動捕獲的,所以這個異常究竟是要在方法內部解決還是交給上層函數去解決其實效果是一樣的。但是我查了很多資料,即使會拋出異常能被系統所捕獲的話還是建議針對方法寫一個throws,因為這樣在完成一個大型任務的時候可以讓別的程序員知道這里會出現什么異常。
如果是自己定義的異常,則必須要用throws拋出該方法可能拋出的異常,否則編譯會報錯。
相關文章
IDEA(2022.2)搭建Servlet基本框架超詳細步驟
這篇文章主要給大家介紹了關于IDEA(2022.2)搭建Servlet基本框架超詳細步驟,Servlet容器負責Servlet和客戶的通信以及調用Servlet的方法,Servlet和客戶的通信采用"請求/響應"的模式,需要的朋友可以參考下2023-10-10