雜談——Java中throws和throw的區別
之前本帥博主寫過一篇關於try-catch和finally的文章,即try-catch與finally語句塊中使用return的注意事項以及相關引申,這篇文章講述了一些它們之間的注意事項。
這try-catch語句塊中,還有很重要的一點,就是異常。
對於異常,我們從來都不陌生。可以說,自從我們第一次寫程式碼到現在的第n次寫程式碼,異常從未離我們遠去,甚至隨著我們學習面的逐漸曠闊而變得越發的頻繁與複雜。
程式中丟擲異常呢,其實有三種方式。一種就是我們最初的時候就開始遇見的,也就是最常出現的,由系統丟擲異常。
所有系統定義的編譯和執行異常都可以由系統自動丟擲,稱為標準異常 |
什麼時候系統會自動丟擲異常呢?
當程式語句出現一些邏輯錯誤、主義錯誤或型別轉換錯誤時,系統會自動丟擲異常。 |
舉個栗子:
public static void main(String[] args) {
int a = 5, b =0;
System.out.println(5/b);
}
系統會自動丟擲ArithmeticException異常,如圖:
或者
public static void main(String[] args) { String s = "abc"; System.out.println(Double.parseDouble(s)); }
系統會自動丟擲NumberFormatException異常,如圖:
上面看了一些系統自動丟擲異常的例子,不過這個不是咱們今天的主菜。咱們今天呢,主要看看我們另外兩種丟擲異常的方式,即throw和throws,使用者程式自定義的異常和應用程式特定的異常,就必須藉助這兩種方式來定義丟擲異常。
1.throw
throw是語句丟擲一個異常。
語法:
throw (異常物件);
如 throw e;
throw丟擲異常不一定是真的出錯了,只要符合條件,你就可以丟擲異常。
舉個例子:
public class test {
public static void main(String[] args) {
String s = "Searchin";
if(s.equals("Searchin")) {
throw new NumberFormatException();
} else {
System.out.println(s);
}
}
}
執行結果如下:
2.throws
throws是方法可能丟擲異常的宣告。(用在宣告方法時,表示該方法可能要丟擲異常(丟擲的是一個異常類物件,這個物件帶有所發生異常的資訊))
語法:
[(修飾符)](返回值型別)(方法名)([引數列表])[throws(異常類)]{......}
public void doA(int a) throws Exception1,Exception3{......}
我們可以使用已有的異常類,也可以自己定義一個異常類。如果我們需要丟擲一個具體的異常資訊可以用JAVA中已有的異常類構造一個新的異常類物件,把相應的異常資訊傳給它就可以了。比如:
public class Test {
public void A() throws IOException{
int i=0;
if(i==0) {
throw new IOException("i不能等於0,請換一個數字");
}
}
//主函式入口
public static void main(String[] args) throws IOException {
Test t=new Test();
t.A();
}
}
程式執行結果如下:
可以看到這裡,我們就將IO異常輸出了。那自定義的異常都會這樣輸出嘛?
我們將上面的程式改一下:
public class Test {
public void A() throws IOException{
int i=0;
if(i==0) {
throw new IOException("i不能等於0,請換一個數字");
}
}
//主函式入口
public static void main(String[] args) {
Test t=new Test();
try {
t.A();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("這個方法出錯啦");
}
}
}
執行結果如下:
通過這兩個程式,我們可以知道,在第一個程式中我們沒有對異常進行處理,因此需要給main方法加上throws IOException,將異常提交給上級來處理。它的上一級是誰呢?那當然是JVM啦。A方法的上一級是main函式,main函式的上一級也就是JVM,如果main函式不處理異常,那麼JVM會處理異常。JAVA虛擬機器根據IOException所帶的異常資訊,判斷這是自定義的異常,於是終止程式,並且打印出報錯資訊。
而在第二個程式中,因為在main函式捕捉到異常並進行了處理(即輸出“這個方法出錯啦”),因此就不需要靠上一級來解決問題啦。
如果想要知道異常的內容,只需要藉助printStackTrace()即可。即
程式執行結果如圖:
3.throw與throws的異同
throw與throws的區別:
throw與throws的共同點:
- throws出現在方法函式頭;而throw出現在函式體。
- throws表示出現異常的一種可能性,即主要是宣告這個方法會丟擲這種型別的異常,使它的呼叫者知道要捕獲這個異常。但是並不一定會發生這些異常;throw則具體向外拋異常的動作,執行throw則一定丟擲了某種異常(異常例項)。
- 兩者都不會由函式去處理異常。它們只是丟擲或者可能丟擲異常,真正的處理異常由函式的上層呼叫處理。
4.總結
異常是會一層層往上拋的,直到遇到了某個方法處理了這個異常或者最後拋給了JVM。但是如果都把異常讓JVM去處理,這並不是一個好的習慣,因為JVM對異常的處理比較寬泛的,它無法具體到一些細節的問題上。所以我們最好我們自己定義一個catch去處理這個異常。至於怎麼處理異常,大家可以參照try-catch與finally語句塊中使用return的注意事項以及相關引申(這篇部落格有提及相關知識)。此外,書上和網上都有很多具體的例子,大家可以參照一些網上提供的例子。
好啦,以上就是關於throw與throws異同的相關知識總結啦,如果大家有什麼不明白的地方或者發現文中有描述不好的地方,歡迎大家留言評論,我們一起學習呀。
Biu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~pia!
注:如果想要了解Java中都有哪些異常,可以參考:java中都有哪些異常