java異常處理 | 菜鳥教程
異常的體系 Throwable
Error
通常指JVM出現重大問題如:執行的類不存在或者記憶體溢位等。
不需要編寫針對程式碼對其處理,程式無法處理。
Exception
在執行時執行出現的一些情況,可以通過try,catch,finally處理
1.異常處理兩種方式:
1、捕獲異常:try catch 直接處理可能出現的異常!
2、宣告異常:throws 宣告告訴呼叫者可能的異常,暴露問題,呼叫者自己處理!
我的總結:
Exception 和 Error的子類名大都是以父類名作為字尾。
Java異常其實是對不正常情況的一種描述,並將其封裝成物件;
Java在 設計異常體系時,將容易出現的異常情況都封裝成了物件。
2、異常處理格式
異常處理的5個關鍵字
try ,catch,
finally
throw, throws
我的總結:
捕獲異常:先捕獲小異常再捕獲大異常。
程式是調出來的,不是寫出來的;多測試是程式設計師的必修課。
異常處理後,程式不會因為出現異常而退出!
異常處理格式
try{
//可能出異常的程式碼
} catch(異常類 物件){
//處理該異常型別的語句
}
[finally] {
//一定會執行的程式碼
//catch塊使用System.exit(1);除外
}
備註:當try語句塊出現異常,程式會自動跳到catch語句塊去找匹配的異常型別,並執行異常處理語句,finally語句塊是異常的統一出口。
3、多異常處理
宣告異常時儘可能宣告具體異常型別,方便更好的處理;
方法宣告幾個異常就對應有幾個catch塊;
若多個catch塊中的異常出現繼承關係,父類異常catch塊放在最後;
在catch語句塊使用Exception類作為異常型別時:
所有子類例項都可以使用父類接收(向上轉型),即所有的異常物件都可以使用Exception接收;
注:在java處理多異常時捕獲小範圍的異常必須放在大範圍異常之前。
java7 - 同時捕獲多個異常型別
Java7之前:
try { int a = Integer.parseInt("1"); int b = Integer.parseInt("0"); int c = a / b; System.out.println(c); } catch (NumberFormatException e) { e.printStackTrace(); } catch(ArithmeticException e) { e.printStackTrace(); }
Java7:將多個異常寫到了同一個catch程式碼塊
try {
Integer a = Integer.parseInt("1");
Integer b = Integer.parseInt("0");
Integer c = a / b;
System.out.println(c);
} catch (NumberFormatException
| ArithmeticException e ) {
e.printStackTrace();
}
4、異常的分類
異常分類:
編譯時被檢查異常; —> Checked異常
在程式中必須使用try…catch處理;
編譯時不被檢測的異常; —> Runtime異常
可以不使用try…catch處理,但一旦出現異常就將由JVM處理。
異常的分類之Runtime異常
RuntimeException(執行時異常)是指因設計或實現方式不當而導致的問題.
說白了,就是程式設計師造成的,程式設計師小心謹慎是完全可以避免的異常.比如,事先判斷物件是否為null就可以避免NullPointerException異常,事先檢查除數不為0就可以避免ArithmeticException異常;
特點:
這種異常Java編譯器不會檢查它,也就說程式中出現這類異常的時候,即使不處理也沒有問題,但是一旦出現異常,程式將異常終止,若採用異常處理,則會被相應的程式執行處理.
異常的分類之Checked異常
除了RuntimeException以及子類,其他的Exception及其子類都是受檢查異常,我們也可以稱為非RuntimeException異常.
特點:
Java編譯器會檢查它,也就說程式中一旦出現這類異常,要麼是沒有try-catch語句捕獲,或throws語句沒有宣告丟擲它,編譯就不會通過,也就說這種異常,程式要求必須處理.
5、宣告異常(throws)
在可能出現異常的方法上宣告丟擲可能出現異常的型別:
宣告的時候儘可能宣告具體的異常,方便更好的處理.
當前方法不知道如何處理這種異常,可將該異常交給上一級呼叫者來處理(非RuntimeException型別的異常)。
方法一旦使用throws宣告丟擲方法內可能出現的異常型別, 該方法就可以不再過問該異常了;
一個方法呼叫另一個使用throws宣告丟擲的方法,自己要麼try…catch , 要麼也throws;
格式:
public 返回值型別 方法名(引數列表…)
throws 異常類A,異常類B… {
}
6、throw
自行丟擲一個異常物件,丟擲異常類的物件;
若throw丟擲的是Runtime異常:
程式可以顯示使用try…catch來捕獲並處理,也可以不管,直接交給方法呼叫者處理;
若throw丟擲Checked異常:
要麼放在try裡自己處理,要麼放在一個throws宣告的方法裡面,交給呼叫者處理。
public static void main(String[] args) {
try {
fn1(1);
} catch (Exception e) { e.printStackTrace(); }
fn2(2);
}
public static void fn1(int a) throws Exception{
if(a >0) { throw new Exception("fn1 -- a值不合法"); }
}
public static void fn2(int a) {
if(a >0) { throw new RuntimeException("a值不合法"); }
}
throws & throw
throws用於在方法上宣告該方法不需要處理的異常型別。
throw用於丟擲具體異常類的物件。
throws與throw的區別:
thorws用在方法上,後面跟異常類名,可以是多個異常類。
throw用在方法內,後面跟異常物件,只能是一個。
7、finally
異常的統一出口:
不管try塊程式是否異常,也不管哪個catch執行,finally塊總會執行。
try語句塊或會執行的catch語句塊使用了JVM系統退出語句例外;//System.exit(1);
try塊必須和 catch塊或和finally同在,不能單獨存在,二者必須出現一個。
不要在finally中使用return 或throw語句,否則將會導致try、catch中的return或throw失效。
我的總結:finally程式碼塊只在一種情況下不執行:System.exit(0);
package reviewDemo;
public class Demo19 {
public static void main(String[] args) {
try{
System.out.println(17/0);
}catch(Exception e){
//e.printStackTrace();
System.out.println("程式錯誤,請修正!");
}finally{
System.out.println("這是finally程式碼塊!");
}
}
}
輸出:
程式錯誤,請修正!
這是finally程式碼塊!
8、throw和catch同時使用
當異常出現在當前方法中,程式只對異常進行部分處理,還有一些處理需要在方法的呼叫者中才能處理完成,此時還應該再次丟擲異常,這樣就可以讓方法的呼叫者也能捕獲到異常;
public static void buy(String price) throws Exception {
try {
if(price != null)
Double.parseDouble(price);
} catch (Exception e) {
e.printStackTrace();
throw new Exception("價格不能只能是數字組成");
}
}
public static void main(String[] args) {
try {
buy(null);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}