public class Test01 {java public static void main(String[] args) {數據庫 Scanner sc = new Scanner(System.in);數組 System.out.println("請輸入第一個數:");jvm
int num1 = 0;ide if(sc.hasNextInt()) { this num1 = sc.nextInt();spa
System.out.println("請輸入第二個數:");.net int num2 = 0;指針 if(sc.hasNextInt()) {orm num2 = sc.nextInt();
if(0 == num2) { System.out.println("除數不能爲0!"); }else { int r = num1 / num2; System.out.println("num1/num2 = "+r); }
}else { System.out.println("第二個數輸入不是數字"); }
}else { System.out.println("第一個數輸入不是數字!"); } } } |
缺點:
[1] 經過判斷影響執行效率。
[2] 判斷邏輯和業務邏輯交織在一塊兒,可維護性不好。
異常是指在程序的運行過程當中所發生的不正常的狀況,它會中斷正在運行的程序
異常處理機制
java中經過異常處理機制爲程序提供異常處理的能力,保持程序繼續運行而不中斷!
涉及異常處理的關鍵字有try…catch/try…catch…finally
把有可能產生異常的代碼放到try代碼塊中,catch代碼塊負責捕獲並處理異常。
[1]正常執行,沒出現任何異常
[2]出現異常,異常處理,正常結束
Exception是全部異常類的直接或者間接父類。
異經常見方法
printStackTrace:打印異常的執行堆棧信息
java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:864) at java.util.Scanner.next(Scanner.java:1485) at java.util.Scanner.nextInt(Scanner.java:2117) at java.util.Scanner.nextInt(Scanner.java:2076) at cn.sxt02.exception02.Test01.main(Test01.java:14) |
通常而言,異常堆棧信息不少,開發者只須要看懂
第一行:異常簡單信息(異常類型,異常的描述等)
最後一行:異常出現的位置(類->方法->方法具體的行)
在控制檯中異常堆棧信息輸出位置不固定
getMessage:返回異常的描述信息
package cn.sxt02.exception02; import java.util.Scanner; public class Test01 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("請輸入第一個數:");
int num1 = 0; int num2 = 0;
try { num1 = sc.nextInt();
System.out.println("請輸入第二個數:"); num2 = sc.nextInt();
int r = num1 / num2; System.out.println("num1/num2 = " + r); }catch (Exception e) { System.out.println("程序出現異常"); // 打印異常的信息 // System.out.println(e.toString());
// 打印異常堆棧信息 e.printStackTrace();
// 返回異常的描述信息,若是沒有信息,返回null(InputMismatchException 沒有描述信息) System.out.println(e.getMessage()); }
System.out.println("程序正常結束"); } }
|
[3]異常類型不匹配
[4] 多重catch
public class Test03 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("請輸入第一個數:");
int num1 = 0; int num2 = 0;
try { num1 = sc.nextInt();
System.out.println("請輸入第二個數:"); num2 = sc.nextInt();
int r = num1 / num2; System.out.println("num1/num2 = " + r); }catch (ArithmeticException e) { System.out.println("數學計算異常:"+e.getMessage()); }catch(InputMismatchException e) { System.out.println("輸入不匹配異常:"+e.getMessage()); }catch (Exception e) { System.out.println("發送異常:"+e.getMessage()); }
System.out.println("程序正常結束"); } } |
把有可能產生異常的代碼放到try中,catch負責匹配並處理異常,finally塊用於進行收尾工做(關閉數據庫、關閉文件、釋放內存等資源)
無論是否發生異常,finally都執行。
public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("請輸入第一個數:");
int num1 = 0; int num2 = 0;
try { num1 = sc.nextInt();
System.out.println("請輸入第二個數:"); num2 = sc.nextInt();
int r = num1 / num2; System.out.println("num1/num2 = " + r); } catch (Exception e) { System.out.println("程序出現異常"); } finally { System.out.println("無論是否出現異常,finally都執行"); }
System.out.println("程序正常結束"); } |
finally 老是執行,經常使用進行收尾類工做。
特殊狀況(B)
[1] finally不執行的狀況。
System.exit(0) 正常推出jvm,finally不會執行。
[2]catch能夠省略,變成try…finally塊。
存在return的try/catch/finally執行順序
package cn.sxt02.exception03;
/** * 存在return的狀況 */ public class Test02 {
public static int div(int a, int b) {
try { int r = a / b; return r;
} catch (Exception e) { System.out.println("出現異常");
return 0;
} finally { System.out.println("我是finally"); }
}
public static void main(String[] args) {
int r = Test02.div(10, 0); System.out.println("r=" + r); System.out.println("程序正常結束"); } }
|
Throwable 類是 Java 語言中全部錯誤(Error)或異常(Exception)的父類,只有當對象是此類(或其子類之一)的實例時,才能經過 Java 虛擬機或者 Java throw 語句拋出。
Error 類表示錯誤類。僅靠程序自己沒法恢復的嚴重錯誤。jvm內存耗盡、jvm崩潰等。
Exception 類表示異常類,能夠經過java 異常處理機制處理。
Exception 根據是否處理分爲兩種狀況。
RuntimeException:運行時異常。不要求程序必須作出處理。是全部運行時異常的父類。
CheckedException:檢查時異常。要求程序必須處理,不處理編譯不經過。
public class Test01 { public static void main(String[] args) { // 運行時異常 Scanner sc = new Scanner(System.in); // runtime exception int r = sc.nextInt(); System.out.println("r = "+ r);
// 檢查時異常 SimpleDateFormat df = new SimpleDateFormat(); try { Date date = df.parse("2019"); } catch (ParseException e) { e.printStackTrace(); } } } |
常見的運行時異常
ArithmeticException:數學計算異常。好比除數爲0
InputMismatchException:輸入不匹配異常
ArrayIndexOutofBoundsException:數組下標越界異常。
NullPointException:空指針異常,對象沒有初始化就使用時,jvm會拋出該異常
IllegalArgumentException:非法參數異常。
ClassCastException:強制類型轉換異常。
NumberFormatException:數字格式化異常。好比把「abc」格式化成數字。
常見的檢查時異常:
ClassNotFoundException:類沒有被發現異常。
SQLException:數據庫相關異常
IOException:IO操做異常
ParseException:解析錯誤異常
FileNotFoundException:文件未發現異常。
運行時異常和檢查時異常的區別
運行時異常:包括RuntimeException及其全部子類。不要求程序必須對它們做出處理,好比InputMismatchException、ArithmeticException、NullPointerException等。即便沒有使用try-catch或throws進行處理,仍舊能夠進行編譯和運行。若是運行時發生異常,會輸出異常的堆棧信息並停止程序執行。
Checked異常(非運行時異常):除了運行時異常外的其餘異常類都是Checked異常。程序必須捕獲或者聲明拋出這種異常,不然出現編譯錯誤,沒法經過編譯。處理方式包括兩種:經過try-catch捕獲異常,經過throws聲明拋出異常從而交給上一級調用方法處理
當一個方法可能存在異常,而此時自身又沒法更好的處理,能夠交給外界處理。此時用throws聲明並拋出異常。
public class Test01 {
public static int div(int a, int b) throws ArithmeticException{ int r = 0; r = a / b; return r; }
public static void main(String[] args) { try { Test01.div(10, 0); } catch (ArithmeticException e) { System.out.println("除數不能爲0"); } } } |
開發者能夠根據須要聲明檢查時異常(Exception或者非運行時異常)和運行時異常(RuntimeException或其子類)
若是調用處也不知道如何處理異常,可選擇繼續聲明異常,咱們把這個過程稱爲異常上拋。
public class Test01 {
public static int div(int a, int b) throws Exception{ int r = 0; r = a / b; return r; }
public static void main(String[] args) throws Exception{
//【1】 調用處知道如何處理! /* try { Test01.div(10, 0); } catch (Exception e) { e.printStackTrace(); } */
// 【2】調用處也不知道如何處理 Test01.div(10, 0);
} } |
聲明異常和重載沒有任何關係
public class Test01 {
public static int div(int a, int b) throws Exception{ int r = 0; r = a / b; return r; }
public static int div(int a, int b) { int r = 0; r = a / b; return r; } } |
方法重載
[1]方法名相同
[2]參數列表不一樣(個數、類型、順序)
[3]和返回值、修飾符、聲明異常無關。
聲明一個和方法重寫有關係。
[1]父類方法聲明瞭異常(檢測時或運行時),子類能夠不聲明任何異常。
public class Father {
public void showInfo() throws Exception{
} }
|
public class Son extends Father{
public void showInfo(){
}
} |
能夠認爲:父類方法拋出異常,子類在重寫過程當中把該異常處理掉了,因此子類方法不用聲明異常。
[2] 父類方法聲明沒有聲明任何異常(檢測時或運行時),子類也不聲明異常或者聲明運行時異常。
public class Father {
public void showInfo(){
} } |
public class Son extends Father{
public void showInfo() throws Exception{
}
} |
[3] 父類聲明瞭異常(檢測時或運行時),子類聲明徹底同樣的異常。
public class Father {
public void showInfo() throws Exception{
} } |
public class Son extends Father{
public void showInfo() throws Exception {
}
} |
除了系統自動拋出異常外,有些問題須要開發者手動拋出異常。使用關鍵字throw
package cn.sxt02.exception06;
public class Student { private String name; private String gender;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getGender() { return gender; }
public void setGender(String gender) throws Exception{ if(gender.equals("男") || gender.equals("女")) { this.gender = gender; }else { throw new Exception("性別不合法!"); } }
public Student(String name, String gender) { super(); this.name = name; this.gender = gender; }
public Student() { super(); }
}
|
public class Test01 { public static void main(String[] args){ Student stu = new Student(); stu.setName("二狗"); try { stu.setGender("xxx"); } catch (Exception e) { System.out.println(e.getMessage()); } } } |
若是開發者須要手動拋出的異常在系統不存在,能夠自定義異常。
若是要自定義異常,首先要肯定異常類型,若是異常是運行時異常,必須繼承RuntimeException或其子類;若是異常是檢查時異常,必須繼承Exception或其子類。
異常的命名方式,參考系統命名方式,以Exception結尾。
public class AgeException extends Exception{
public AgeException() { super(); }
public AgeException(String message) { super(message); }
} |